Appearance
Economy Module
Overview
The economy module currently owns Economy V1 audition-fee payment facts. It quotes the fee, confirms user-initiated SignedVault deposits, creates paid clone shells, records purchase state, and grants clone entitlements through Clone Service.
Economy V2 will later own race tickets, pool splits, payout authorization facts, creator royalties, and protocol rake.
Responsibilities
- Quote audition-fee price by capacity tier and model tier.
- Confirm SignedVault deposit state on-chain after the wallet transaction is mined.
- Create the clone shell and default strategy draft after a paid creation deposit verifies.
- Persist purchase rows and idempotency state.
- Grant clone capacity entitlement after verified payment. The initial clone purchase's entitlement is the paid slot for the clone's first audition.
- Grant entitlements to existing owned clones for upgrade/retry flows.
- Provide SignedVault client/config helpers.
- Provide withdrawal-signing helper used by future payout/refund flows.
Boundary Rules
- Economy owns payment and purchase facts, not clone strategy or lifecycle outcomes.
- Clone Service owns effective entitlement projection after a grant.
- Lifecycle owns audition state, evaluation, voiding, and refund-authorization rows for voided auditions.
- Race ticket purchases and settlement payout facts should be new Economy-owned rows, not reused audition-fee rows.
Runtime Flow
Quote:
text
Request capacity tier + model tier
-> validate tier combination
-> return hard-coded v1 ETH quoteConfirm:
text
Authenticated user submits clone target + v1 deposit nonce
-> idempotency check purchase row
-> verify SignedVault deposit by resolver address and nonce when needed
-> create clone shell/default draft when `createClone` is present
-> insert or reuse purchase
-> upsert clone entitlement
-> mark purchase granted
-> return entitlement and a minimal payment confirmationDeposit idempotency is keyed internally by (resolverAddress, depositNonce). The nonce is part of the v1 confirmation request because the backend does not yet create a server-side purchase intent or run a SignedVault watcher. A future checkout/intent flow can let clients confirm by intent id or clone id instead.
Main Code Paths
| Path | Purpose |
|---|---|
backend/src/modules/economy/pricing/audition-fee.ts | Hard-coded v1 audition-fee pricing matrix. |
backend/src/modules/economy/audition-fee/service.ts | Deposit verification, paid clone creation, purchase upsert, entitlement grant. |
backend/src/modules/economy/repositories/purchases.ts | economy_purchases persistence and idempotency. |
backend/src/modules/economy/chain/signed-vault-config.ts | MegaETH SignedVault env config. |
backend/src/modules/economy/chain/client.ts | Public and resolver wallet client factories. |
backend/src/modules/economy/chain/deposit-verifier.ts | Reads SignedVault deposit state. |
backend/src/modules/economy/chain/withdrawal-signer.ts | EIP-712 withdrawal signatures for refunds/future payouts. |
backend/src/api/routes/economy.ts | Audition-fee HTTP route family. |
State And Tables
| Migration | Tables |
|---|---|
0006_economy_purchases.sql | economy_purchases |
0015_audition_purchase_idempotency.sql | Audition purchase idempotency support. |
| Table | Technical significance |
|---|---|
economy_purchases | Audition-fee purchase, deposit identity, status, user/clone/tier/model, entitlement sync fields. |
clone_capacity_entitlements | Written through Clone Service after payment grant; consumed by runtime guards. |
Purchase status flow is confirmed -> granted, or failed when verification fails.
Routes And Workers
| Route | Auth | Purpose |
|---|---|---|
POST /api/v1/economy/audition-fee/quote | Bearer | Return audition-fee quote for capacity/model tier. |
POST /api/v1/economy/audition-fee/submit | Bearer | Confirm/sync the authenticated wallet's post-transaction deposit; backend verifies wallet ownership and amount before creating a paid clone when requested and returning entitlement. |
Economy has no worker today. Future ticket/payout reconciliation workers belong here.
Pricing Matrix
V1 quotes are hard-coded in ETH:
| Model tier | Starter | Builder | Pro |
|---|---|---|---|
cheap | 0.01 | 0.015 | 0.02 |
medium | 0.02 | 0.03 | 0.04 |
best | 0.04 | 0.06 | 0.08 |
Capacity tiers map to active-asset ranges:
| Tier | Active assets |
|---|---|
starter | 1-3 |
builder | 4-6 |
pro | 7-10 |
Failure Behavior
- If SignedVault config is missing, submit returns service unavailable.
- Clone Service does not expose direct paid clone creation; Economy submit with
createCloneis the only paid creation path. - RPC/verifier unavailability maps to a service-unavailable style failure.
- Deposit mismatch maps to validation failure.
- A granted purchase retried with the same resolver/nonce returns the existing entitlement with
alreadyGranted=true. - A failed purchase for the same deposit blocks reuse.
- A concurrent unique deposit conflict maps to
409 concurrent_submit. - Verification failures mark existing pending/confirmed purchase rows failed when possible.
Debugging Notes
- For duplicate submit behavior, inspect resolver address, deposit nonce, and purchase status first.
- If entitlement does not appear after a granted purchase, inspect entitlement sync fields on both
economy_purchasesandclone_capacity_entitlements. - If local submit is unavailable, check SignedVault env config before debugging chain state.
- Refund authorization for voided auditions is stored by Lifecycle in
audition_refund_authorizations; Economy purchase rows are not changed by that flow.
Tests
bash
cd backend
npm run typecheck
node --import tsx --test test/api-economy.test.ts test/audition-fee-*.test.ts test/withdrawal-signer.test.tsKnown Gaps
- Economy V2 race-ticket payment rows and APIs.
- Economy V2 settlement payout authorization rows for ticket winners, creator pool, and protocol rake.
- Production reconciliation, managed secrets, resolver-key handling, and payout monitoring.