Mirrors deploy/testnet/docker-compose.supplier-tts.yml and the simulation
PiperTTS stack, co-located on vector-marketplace as a private internal
service on marketplace-mainnet-net (no Traefik labels, no public DNS for
Piper itself). Supplier reaches Piper at http://marketplace-mainnet-tts-piper:8000.
Voice: en_US-lessac-high. New supplier wallet + on-chain advert are
published out-of-band by the operator per the runbook header.
Files:
- deploy/mainnet/docker-compose.tts-piper.yml openedai-speech-min, private
- deploy/mainnet/docker-compose.supplier-tts.yml CAPABILITY_KIND=tts supplier
- deploy/mainnet/install-voice-extras.sh voice download + yaml mapping
- deploy/mainnet/voice-mappings.py idempotent yaml editor
- supplier/.env.tts.example operator env template
- .gitignore whitelist .env.*.example
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a Codex/ChatGPT backend path for the supplier alongside the
existing Ollama one. The mainnet supplier is repointed at a localhost
ChatMock proxy (RayBytes/ChatMock, pinned :v1.35) that authenticates
against a ChatGPT Pro subscription via OAuth.
- supplier/src/openai.ts: HTTP client for OpenAI-compatible
/v1/chat/completions. Same return shape as ollama.callOllama so
jobRunner can branch cleanly.
- supplier/src/jobRunner.ts: branch on config.llmBackend.
- supplier/src/config.ts: LLM_BACKEND ("ollama" default | "openai"),
OPENAI_BASE_URL, OPENAI_TIMEOUT_MS (default 180_000 — GPT first-token
latency).
- supplier/src/cli/gen-keypair.ts: standalone Ed25519 keypair generator
+ bech32 address derivation. Used to bootstrap a fresh supplier
wallet without round-tripping through tx:post-advert --dry-run.
- deploy/mainnet/docker-compose.chatmock.yml: long-running chatmock
serve + one-shot --profile login flow.
- deploy/mainnet/docker-compose.supplier.yml: rewritten for openai
backend; Traefik routes at mp-suppliers-gpt.vector.apexfusion.org so
the unsuffixed slot stays free for a future supplier with a
different backend.
- tests/unit/supplier-openai.test.ts: unit coverage for callOpenAi.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Splits the single `lovelacePerOutput` param in publishReferenceScripts.ts
into `escrowLovelace` and `advertLovelace`, exposed via env vars
ESCROW_PUBLISH_LOVELACE / ADVERT_PUBLISH_LOVELACE in the CLI. Defaults
unchanged at 30 AP3X each (60 AP3X total).
Motivation: mainnet rollout where the publishing wallet has only ~57 AP3X
(buyer wallet) — needs to publish at calculated min-utxo (~17 AP3X escrow
+ ~7 AP3X advert = 24 AP3X total) instead of the safe 60 AP3X default.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Static re-exports from tx/index.ts caused vite to trace
loadEscrowScript/loadAdvertScript/buildLiveTxForPublishReferenceScripts
into the buyer UI bundle, hitting the CML WASM "ESM integration proposal"
limitation. Sibling builders avoid this with /* @vite-ignore */ dynamic
imports; we keep symmetry by parking the helpers on a separate
@marketplace/shared/tx/server entry that the buyer never imports.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When ESCROW_REF_UTXO / ADVERT_REF_UTXO env vars are set (format
<txhash>#<idx>), Claim/Submit/Accept/Reclaim/RetireAdvert call
.readFrom([refUtxo]) instead of inlining the validator CBOR via
.attach.SpendingValidator(). Lucid-evolution 0.4.30 auto-extracts
utxo.scriptRef into the script-witness map (dist/index.js:1903–1913),
so no separate attach call is needed. Default (env unset) is unchanged.
Adds buildLiveTxForPublishReferenceScripts (a one-shot tx that
publishes both validators as scriptRef-bearing UTxOs at a caller-
supplied address — typically the all-zero-pkh enterprise burn address)
and the supplier tx:publish-reference-scripts CLI that wraps it.
Targeted at testnet trial; mainnet rollout is a separate flip after
verification.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes 2/4 builders from the M1-F-D-defer list (postAdvert already live in
7ea7328; updateAdvert and release remain).
Reclaim:
- buildLiveTxForReclaim in liveCbor.ts (mirrors buildLiveTxForAccept):
spends the escrow UTxO with REDEEMER_RECLAIM (Constr3), pays
payment + buyer_bond + supplier_bond to buyer, delegates UPLC eval
to Ogmios via localUPLCEval:false. Validity range = tipMs ± 60s.
- reclaim.ts: replace the unconditional mockSlotToWallclockMs tipMs
computation with `isLive ? Date.now() : mockSlotToWallclockMs(tipSlot)`,
matching accept.ts:77. Adds the live-CBOR dispatch branch.
Funds-at-risk before this fix: with the broken tipMs path, every live
Reclaim was rejected client-side ("tip < deliver_by" using a Nov-1970
tip). If a supplier never Claimed, buyer's 6-7 AP3X stayed locked
indefinitely. Verified recovery of 4 stuck escrows on Vector L2 testnet
(txs f6660e52, 769f16fd, 79970d86, 9f4db14b — 14 AP3X total recovered).
RetireAdvert:
- buildLiveTxForRetireAdvert in liveCbor.ts: spends advert UTxO with
REDEEMER_RETIRE_ADVERT (Constr2), advert script address.
- retireAdvert.ts: live-CBOR dispatch.
- supplier CLI: retire-advert.ts + retireAdvertFlow.ts.
- supplier/package.json: tx:retire-advert script.
Indexer:
- follower/blockProcessor + worker: handle RetireAdvert events,
transition advert row state to Retired.
- db/cache.ts: markAdvertTerminal helper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>