Lilith Metaverse · Architecture

Commerce & Royalties

A focused page within the Lilith Metaverse Architecture documentation. The full map and every sibling page live in the Architecture hub.

7sections12 minread1diagram

On this page

V3 ("Lilith") sells three different things to three different rooms: a stadium ticket to a Saraswati concert, a tip dropped into a yoga instructor's jar mid-class, and a limited signed edition of an AI-generated track. The hard part is not charging the card — it is making the money land correctly afterward. A concert ticket has to be named-on-issue, capped per fan, and resalable only as a no-markup signed return so scalpers can't farm it. A track's revenue has to split — at generation time, before a single stream plays — between the artist, the producer, the platform reserve, and the human voice contributors and rights-holders whose work the AI persona depends on, then settle to each of them per quarter, on-chain, in fiat or crypto depending on where they live. And when a track is taken down for a rights violation, every ticket, replay, and signed edition that touches it has to unwind within a day, with royalties paused and restitution routed. Commerce in Lilith is therefore not a checkout button — it is a ledger discipline.

That discipline lives in one real Rust service, apps/v3/lilith-commerce-service, which computes every split, receipt, route, and refund deterministically and audits each one into V1; and it settles through the shared Aje payment substrate (libs/oshun/payments-bridge, composing libs/aje/*) so a fiat Stripe charge and an on-chain crypto invoice grant the same entitlement through the same bus. This page is the architecture-side companion for the commerce and creator-monetization story in the "Trust, Rights, Commerce, and Operations" set; the section hub is ../V3_ARCHITECTURE.md.

What ships, honestly#

The commerce engine is real, tested Rust, not a spec. lilith-commerce-service is a ~14.8 K-line crate of thirteen domain flow modules plus the Tara split engine in lib.rs, and it carries 151 unit tests that pass green (cargo test -p lilith-commerce-service151 passed; 0 failed, verified on box). The tests are not truthiness checks — they assert exact computed ledger amounts: a 10,000-cent paid class routes 2_000 to platform and 8_000 to the instructor; a 1,001-cent donation routes 100/901 with the rounding remainder deliberately assigned to the creator; a track waterfall that doesn't total exactly 10,000 bps is rejected. The split math, validation, anti-scalp checks, refund-tier classifier, store-policy gate, and audit-event derivation are all domain-specific and exercised against known-correct values.

The shared Aje payments-bridge is also real: @oshun/payments-bridge (libs/oshun/payments-bridge) is a substantive library with Ed25519 receipt signing (@noble/curves), a cold-spend co-signing queue, an admin/refund surface, and an 18-rail entitlement bus that makes four fiat processors (Stripe, Adyen, PayPal, generic) and fourteen crypto chains emit structurally identical entitlement events. The TS-side V3 royalty surfaces — isis-music's track provenance bundle (which stamps the aje:royalty-waterfall:saraswati-stage-v1 policy at generation), tara-studio's TTS voice-royalty distribution, and saraswati-stage's Themis rights adjudication — are real basis-point code with their own tests.

Two honest qualifications. First, the commerce crate's job is the ledger, not the wire. Functions like complete_tara_stripe_connect_onboarding and withdraw_tara_instructor_aje_native validate the request (supported region, valid aje_ wallet, sufficient balance), compute the routes, and emit a provider-shaped receipt with deterministic IDs (acct_tara_us_…, po_tara_test_…, aje:withdrawal:lilith-royalty:…, a network_receipt_id) and a Settled/Paid/Complete status. They do not call the live Stripe API or broadcast an Aje transaction from the pure-function path — that execution is the shared substrate's responsibility (Stripe Connect; the payments-bridge cold-spend queue and entitlement bus). The boundary is honest: real money math and a typed settlement contract on this side, real rail execution on the other. Second, the Year-1 catalog — which concerts, which signed-edition drops, which Tara passes — is a schedule the engine executes, not an artifact in the repo. The machinery is shipped; the merchandise is operations.

The commerce surfaces#

The crate's SERVICE_DESCRIPTOR (port 43105) advertises twelve capabilities, each backed by a module. They divide into the four things a creator economy needs: sell access, accept gratitude, sell ownership, and unwind cleanly.

Tickets — named, capped, signed-return-only resale#

lilith_ticket_issuance.rs (2.1 K lines, 15 tests) is the anti-scalp ticket ledger. Tickets are named on issue and capped at four per fan (LILITH_TICKET_PER_FAN_CAP = 4), and the only legal transfer is a LilithTicketResaleMode::SignedReturnOnly flow: the resale cannot exceed the original face value ("anti-scalp signed-return resale cannot exceed original face value") and the buyer can't cross the per-fan cap. Returns are cryptographically tagged with two signature prefixes — sig:lilith-ticket-return: (holder) and sig:lilith-commerce-return: (issuer) — so a return is provable, not assertable. The capacity bands map exactly onto the Stadium-tier seating plan the monolith defines: front-256 (256), hall/mezzanine (768), crowd (3_072), and a 128-seat master class. A no-show seat is reclaimed by promote_lilith_waitlist_no_show_seat inside a 15-minute-pre / 10-minute-post-start window, splitting the upgrade fee 20/80 platform/instructor.

Tips and concert gratitude#

lilith_tip_routing.rs routes a tip to an Instructor, Artist, or SessionHost at 10% platform / 90% recipient (1_000/9_000 bps), over Stripe or Aje, and writes three receipts per tip — payer, recipient, and platform — so all three parties have a record. saraswati_concert_tips.rs is the concert-specific variant (10% platform / 90% artist, settled inside a 60-minute window). The math is the same basis-point engine used everywhere, and the rounding test (1_001 → 100/901) proves the remainder favors the creator.

Subscriptions, passes, and the free tier#

lilith_subscription_billing.rs (832 lines) bills the recurring products — Tara passes, Saraswati Club passes, Commons memberships — on monthly cycles with proration, over Stripe or Aje. saraswati_club_pass.rs is the club-only admission path, and saraswati_free_tier.rs models the no-charge experience (catalog browse, follow, batched light-emoji, small-concert admission) so the free attendee is a first-class commerce state, not an absence of one. lilith_fan_token_boundaries.rs keeps fan-token access benefits behind a per-region legal-review gate — tokens grant access perks, never unregistered financial instruments.

Cancellation, refund, and the 90-day credit ledger#

lilith_cancellation_refunds.rs (2.3 K lines, 22 tests) encodes the three-tier schedule as a real classifier (classify_refund_tier): a full refund at ≥ 24 h before start, a half-refund-half-credit between 1 h and 24 h, no refund inside the hour, and no-show. Credit lands in a 90-day Lilith credit ledger (LILITH_CREDIT_VALIDITY_MS = 90 days). The asymmetry is deliberate and machine-enforced: a platform-fault cancellation adds a 50% goodwill credit (5_000 bps) and must complete within a 24 h SLA, and a provider outage (payment rail or Pixel Streaming) issues a 100% credit (10_000 bps) and pages the lilith-commerce-ops queue. The module also owns refund tax reversal (across five jurisdiction profiles) and chargeback handling (48 h ops SLA, 14-day appeal window). Critically, a platform-fault cancellation pauses the affected concert's royalty waterfall — commerce and royalties are one ledger.

Platform billing bridges — store compliance#

lilith_platform_billing_bridges.rs is the store-policy gate. Where Apple, Google, or Sony require their own billing flow, the bridge validates an Apple IAP / Google Play Billing / PSN Wallet receipt against the real policy references (apple-app-review-guideline-3.1.1-iap, google-play-payments-policy-billing, playstation-store-psn-wallet): it forbids external payment links for in-app digital goods, requires a signed receipt, a passed certification case in the platform's cert namespace, and confirmed entitlement delivery. The point is reconciliation parity — the entitlement is delivered through the same commerce ledger regardless of rail, so a PSN-wallet purchase and a Stripe purchase look identical downstream.

The royalty and revenue-split model#

This is where Lilith's creator-economy thesis lives: AI personas are built on human work, so the people whose voices and rights-holdings feed a persona get paid automatically, by construction, not by goodwill.

The Tara split engine#

lib.rs hosts apply_tara_default_platform_split, the instructor-economy core. A TaraCommercePaymentKind of PaidClass splits 20/80 platform/instructor; Tip/Donation splits 10/90. An instructor can opt a slice of their share into a Lineage Fund endowment, capped at 10% of the instructor share (TARA_LINEAGE_FUND_MAX_INSTRUCTOR_SHARE_BASIS_POINTS = 1_000) — a structured way to fund the teaching tradition. Every split produces a TaraPayoutRoute per recipient and a v1-audit:v3-tara-commerce-split:… event id. Instructor payouts reach a bank via complete_tara_stripe_connect_onboarding (KYC, supported regions AU/CA/DE/FR/GB/NL/US) or a wallet via withdraw_tara_instructor_aje_native (crypto regions BR/CA/GB/IN/KE/NG/PH/SG/US, token aje-native-usdc).

The Saraswati track royalty waterfall#

lilith_royalty_waterfall.rs (1.2 K lines, 14 tests) is the heart of the page. A track's split is encoded at generation timeencode_lilith_track_royalty_waterfall_at_generation must run within 60 minutes of generation (LILITH_TRACK_ROYALTY_WATERFALL_ENCODING_WINDOW_MS) and is anchored to an Aje contract (aje:royalty-waterfall:saraswati:…). The split is validated hard: it must total exactly 10,000 bps, have at least two payees, and include both an Artist and a PlatformReserve role; payees must use the artist: / producer: / contributor: / platform: namespace. The five LilithRoyaltyWaterfallRole variants — Artist, Producer, VoiceContributor, PromptContributor, PlatformReserve — are the mechanism by which the human contributor share is first-class. Revenue then flows in two stages: route_lilith_track_stream_payout pays per-stream events (namespace stream:saraswati:) against the persisted waterfall, asserting the routes match the config; and settle_lilith_quarterly_royalties does the on-chain quarterly true-up (below).

Signed editions and remix rights — secondary royalties#

saraswati_signed_edition.rs (2.2 K lines, 23 tests) mints limited editions of 250 via the Aje primitive aje.signed-edition.mint.v1 inside a 6 h mint window, and — the key creator-protection — enforces a 10% secondary-sale royalty (SARASWATI_SIGNED_EDITION_SECONDARY_ROYALTY_BPS = 1_000) that routes back to creators on every resale. It imports the waterfall roles directly from lilith_royalty_waterfall (cross-module composition, not duplication). A track takedown cascades to outstanding editions within a 24 h SLA, marking them Historical and pausing resale-royalty routing; a holder whose edition is withdrawn chooses to KeepAsHistoricalArtifact or BurnForFullRefund through a Lilith-Rights review queue. saraswati_remix_rights.rs applies the same discipline to licensed remixes: secondary royalty splits must total 10,000 bps and include the original artist and the remixer.

TTS voice-contributor royalties#

On the TypeScript side, libs/v3/tara-studio/src/tts-voice-royalty-distribution.ts settles a separate 5% added royalty (basisPointShareCents(…, 500)) to a voice contributor whenever their cloned voice is used in a payable context (on-demand Aja cue playback, localized dub stream) — and pointedly not for unsupported uses (arbitrary TTS prompts). This is the consent-to-compensation loop the provenance layer promises, expressed as money.

Settlement through the shared Aje substrate#

Every rail converges on one settlement plane so a purchase reconciles identically whether it arrived as fiat or crypto.

flowchart TD subgraph Buy[Purchase surfaces] FIAT[Stripe / Adyen / PayPal] CRYPTO[14 Aje crypto rails] STORE[Apple IAP / Google Play / PSN] end FIAT --> BRIDGE CRYPTO --> BRIDGE STORE -->|store-policy gate| LEDGER BRIDGE[payments-bridge<br/>entitlement bus · Ed25519 receipts] -->|invoice.settled| LEDGER LEDGER[lilith-commerce-service ledger<br/>v3 Postgres schema] --> SPLIT{Split engine} SPLIT -->|tickets / tips / subs| ROUTES[Payout routes] GEN[Track generation] -->|encode waterfall ≤60 min| WF[Aje waterfall contract] WF --> STREAM[Per-stream payout] STREAM --> QTR[Quarterly on-chain settlement<br/>89–92 day window · 6 h grace] ROUTES --> PAYOUT[Stripe Connect · Aje native withdrawal] QTR --> PAYOUT QTR -->|aje:royalty-settlement-audit| CHAIN[(On-chain audit)] ROUTES --> AUDIT[(V1 @oshun/audit-platform)] PAYOUT --> AUDIT QTR --> AUDIT

Rails, receipts, and the entitlement bus#

@oshun/payments-bridge exists to make settlement rail-agnostic. Its entitlement bus defines three topics — payment.invoice.confirmed, payment.invoice.settled, payment.refund.broadcast — whose envelopes are structurally identical across a rail field spanning four fiat rails and fourteen crypto rails (BTC on-chain/Lightning, LTC, five EVM chains, XMR, SOL, TON, Cardano, Ergo, TRON). The entitlement service never learns whether a payment was fiat or crypto; it just grants on invoice.settled. Receipts are signed with Ed25519 against the V1 audit-platform key and canonicalized deterministically (sorted keys, bigints as decimal strings), so a receipt verifies off-box.

Quarterly on-chain settlement#

settle_lilith_quarterly_royalties is the true-up. It refuses to run unless the period covers one real calendar quarter (89–92 days), the settlement was scheduled at or after quarter close, the actual run lands inside a 6 h grace window, and there is a visible Aje on-chain audit id (aje:royalty-settlement-audit:…). It re-derives each role's settlement amount from the same waterfall, emits an aje:settlement-transfer:quarterly:… per route, and only reports completed when it ran on schedule, the on-chain audit is visible, and a positive amount settled. Royalties are thus bounded and provable, not best-effort.

Payouts: Stripe Connect and Aje native#

Both the Tara split engine and the royalty waterfall expose dual payout legs: process_lilith_royalty_stripe_connect_payout for fiat contributors in supported regions, and process_lilith_royalty_aje_native_withdrawal for crypto, each validating region eligibility and balance and emitting a typed receipt. The region lists differ by design — crypto reaches markets where Stripe payouts don't — which is itself the creator-access argument for the Aje rail.

Edge cases and failure modes#

  • Splits can't drift. A waterfall that doesn't total exactly 10,000 bps, or omits an artist or platform-reserve split, is rejected at encode time — there is no "approximately 100%."
  • Resale can't scalp. A signed-return resale above original face value is refused, and a buyer at the per-fan cap can't acquire a fifth ticket through the resale path.
  • Settlement can't run early or stale. The quarterly settler rejects a period shorter than 89 days, a run before quarter close, a run past the 6 h grace window, or a missing on-chain audit id.
  • A takedown unwinds money. lilith_rights_takedown_cascade.rs (24 h SLA) flags archived performances historical, pauses in-world replays, marks signed editions historical and pauses their resale-royalty routing, and fires off-platform takedown notices — and a Themis-adjudicated unlicensed-use claim triggers track unrelease plus royalty restitution.
  • Provider outage is a credit, not a loss. A payment-rail or Pixel-Streaming outage yields a 100% credit and an operator page, distinct from a user's own late cancellation.
  • The ledger seam is explicit. Stripe/Aje/store receipts are typed contracts emitted by pure functions; the live charge, on-chain broadcast, and cryptographic store-receipt validation happen in the rail layer, not the split math. Read a Settled status as "ledger says settle here," with execution on the bridge.

How it connects#

Commerce is downstream of generation and rights. The royalty waterfall is encoded by the Saraswati stage pipeline at track-generation time and stamped into the isis-music provenance bundle, which is why a split exists before the first stream. Every commerce action audits into V1 @oshun/audit-platform and the ticket/refund/credit ledger is DSAR-covered, tying this page to persona policy, provenance, and rights: the same takedown machinery that withdraws a track is what pauses its editions' royalties here. The financial telemetry, release gates, and abuse posture for these flows live in observability, performance, security, and launch. And the shared substrate — @oshun/payments-bridge, @oshun/billing-support, @oshun/audit-platform, and the libs/aje/* rails — sits in the platform map at ../../platform/oshun-domain-libraries.html.