Files
agents-marketplace/supplier/.env.example
jelisaveta-talbot cbab81efbd M1-F: end-to-end LLM marketplace lifecycle on Vector testnet
Bonded-escrow marketplace for prompt → response between buyers and
local-LLM suppliers, settling on Vector (UTxO) via Aiken Plutus V3
validators. Lifecycle PostEscrow → Claim → Submit → Accept proven on
Vector testnet 2026-05-06; AcceptEscrow tx 125e3cfe…7dc100d distributes
payment + bonds per the validator's distribution rule.

Workspace layout (pnpm + TypeScript):
  contracts/marketplace/      Aiken validators (advert + escrow) + plutus.json
  packages/shared/            Tx-builders (lucid-evolution), CBOR codecs,
                              chain providers (mock / read-only / live Ogmios)
  supplier/                   OpenAI-compatible HTTP node (Ollama by default;
                              vLLM / llama.cpp / OpenRouter / OpenClaw all
                              swap-in via OLLAMA_URL); 202+poll chat handler
  buyer/                      Express + React SPA; server-side runs the full
                              chain lifecycle via /v1/submit-prompt and
                              /v1/accept; SPA never holds the buyer key
  indexer/                    Chain-follower (extends apex-dashboard pattern),
                              SSE event stream + REST queries
  indexer-ui/                 Operator dashboard (events + suppliers + escrow
                              lookup)
  tests/                      1098 vitest unit + integration tests (10 skipped
                              under M1-F-D-defer for UPLC test plumbing)
  deploy/testnet/             Per-service docker-compose for the Hetzner stack
  docs/EXECUTIVE_SUMMARY.*    Marp deck (PDF + PPTX) — 11 slides, mermaid
                              diagrams pre-rendered for portable export
  docs/CLOUDFLARE_WAF_BYPASS.md  CF Skip-rule runbook for /v1/* paths
  docs/ARCHITECTURE.md        canonical spec

Live demo (testnet, 2026-05-06):
  https://mp-buyers.vector.testnet.apexfusion.org      (buyer SPA)
  https://mp-suppliers.vector.testnet.apexfusion.org   (supplier API)
  https://mp-indexer.vector.testnet.apexfusion.org     (indexer + UI)
2026-05-06 13:27:48 +02:00

99 lines
4.3 KiB
Plaintext

# supplier/.env.example
#
# Copy to supplier/.env and fill in real values before `docker compose up`.
# .env is gitignored — NEVER commit a populated copy.
#
# To generate a fresh Ed25519 wallet seed:
# openssl rand -hex 32
# Fund the resulting address with ~5 AP3X on Vector testnet via the faucet
# before running. See deploy/README.md §2.
#
# Lines marked SECRET must never be shared, logged, or committed.
# ─── Required ─────────────────────────────────────────────────────────────
# 64-char hex Ed25519 private key seed for the supplier wallet. SECRET.
# Generate via: openssl rand -hex 32
SUPPLIER_PRIV_KEY_HEX=PASTE_64_HEX_CHARS_HERE
# Ogmios WebSocket URL. For external hosted Ogmios (recommended for M1-F):
# wss://ogmios.vector.testnet.apexfusion.org
# For a local Ogmios container (M1-F-vector-stack follow-up): ws://ogmios:1337
OGMIOS_URL=wss://ogmios.vector.testnet.apexfusion.org
# Ollama HTTP base URL. Inside compose this is the service name.
OLLAMA_URL=http://ollama:11434
# OutputReference of this supplier's on-chain advertisement UTxO.
# Format: "<64-hex-tx-hash>#<int-output-index>"
# Posting an advert is a one-shot operation — see deploy/README.md §4.
ADVERT_REF=PASTE_TXHASH_HERE#0
# Cardano network ID. "0" = testnet, "1" = mainnet.
# IMPORTANT: leave at "0" until ARCHITECTURE.md §9 #5 mainnet safety lands.
NETWORK_ID=0
# ─── Optional ─────────────────────────────────────────────────────────────
# HTTP listen port inside the container. Compose maps this to the host.
PORT=8080
# Ollama request timeout (ms). Tiny CPU model on Hetzner CX is slow — keep
# generous. Increase if you see ollama_timeout reasons in logs.
OLLAMA_TIMEOUT_MS=120000
# ─── Optional (not in supplier/src/config.ts; consumed by index.ts boot) ──
# Pre-derived public-key + pkh + bech32 address. M1-D will derive these from
# SUPPLIER_PRIV_KEY_HEX automatically; until then index.ts reads them from
# env. Tests inject WalletKey directly.
# SUPPLIER_PUB_KEY_HEX=
# SUPPLIER_PKH=
# SUPPLIER_ADDRESS=
# ─── Optional — chain provider selection (M1-F-2) ─────────────────────────
# LIVE_CHAIN: opt-in to real Ogmios submitTx + awaitTx.
# Default unset = ReadOnlyOgmiosProvider (no real chain writes; safe for dev).
# Set to literal "1" to enable LiveOgmiosProvider — REAL TESTNET/MAINNET
# SUBMISSIONS WILL HAPPEN. Any other value (including "true", "yes", "TRUE")
# is treated as off, by design (safety against misconfiguration).
LIVE_CHAIN=
# ─── tx:post-advert — run once before first deploy (M1-F-3) ───────────────────
# Execute: pnpm --filter @marketplace/supplier tx:post-advert
# On success, copy the printed "<txHash>#0" string into ADVERT_REF above.
# Capability published in the on-chain advertisement. // added M1-F-3
ADVERT_CAPABILITY_ID=llm.text.generate.v1
# Ollama model name served by this supplier. // added M1-F-3
ADVERT_MODEL=qwen2.5:0.5b
# Maximum output tokens the supplier will honour per request. // added M1-F-3
ADVERT_MAX_OUTPUT_TOKENS=512
# Maximum processing time the supplier guarantees (ms). // added M1-F-3
ADVERT_MAX_PROCESSING_MS=60000
# Flat price per prompt in AP3X lovelace. // added M1-F-3
ADVERT_PRICE_LOVELACE=2000000
# Supplier bond deposited into the advert UTxO (lovelace). // added M1-F-3
# Default 1_000_000 if omitted.
ADVERT_SUPPLIER_BOND_LOVELACE=1000000
# Buyer bond required per escrow (lovelace). // added M1-F-3
# Default 1_000_000 if omitted.
ADVERT_BUYER_BOND_LOVELACE=1000000
# HTTPS endpoint buyers will call (must be publicly reachable). // added M1-F-3
ADVERT_ENDPOINT_URL=https://mp-supplier.vector.testnet.apexfusion.org
# Optional off-chain detail pointer (IPFS / HTTPS URI). // added M1-F-3
# Leave empty for v1 if no extended metadata is published.
ADVERT_DETAIL_URI=
# Optional sha256 of the detail JSON (64 hex chars). // added M1-F-3
# If empty, defaults to sha256("") =
# e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
ADVERT_DETAIL_HASH=