Skip to content
← Back to marketplace

How the marketplace works

A governance-first explainer. Every trust claim below is reducible to a specific piece of on-chain or open-source code.

Purchase lifecycle

Five states. No hidden transitions.

  1. 1. Pending lock

    You chose a template. The server built an unsigned Lock transaction. Nothing is on chain yet.

  2. 2. Locked

    Your wallet signed and submitted the Lock tx. Your ADA is now at the script address. The server has no control over it.

  3. 3. Instantiated

    You spawned a workspace from the template. It seeds the documents, diagrams, and GTT nodes declared in the manifest.

  4. 4. Validated

    As you bring GTT capabilities to `active`, the platform tracks progress. When every required slug is green, you can trigger Release.

  5. 5. Released — or refunded

    Release: you + platform co-sign, seller is paid, platform takes its fee. Refund: after the deadline, you sign alone and reclaim every lovelace.

The smart contract

The full validator source ships in the repo at `contracts/validators/escrow.ak`. It is tiny and deliberately readable. Key facts:

  • Two redeemers: `Release` and `Refund`. Nothing else spends the script.
  • The Datum binds buyer, seller, platform, price, template hash, purchase id, deadline, and fee bps — all fixed at lock time.
  • Fee math is integer-only (`price * bps / 10000`). There's no floating-point rounding and no off-chain math the on-chain code couldn't verify.
  • The script ignores anything that isn't a `Spend`. No governance hooks, no migrations, no admin keys.

Release rules

Both conditions must hold on-chain for a Release tx to spend the lock UTxO:

  • Buyer AND platform must sign (`extra_signatories` contains both key hashes).
  • Output amounts match the fee split: seller receives ≥ `price − fee`, platform receives ≥ `fee`.

The platform's signing rule (off-chain)

The validator allows the platform to co-sign, but the platform itself imposes four guards before producing a signature. These live in `src/lib/cardano/escrow/platform-signer.ts` and are visible in the repo:

  1. Purchase status is `locked` — nothing else, not `released` or `refunded`.
  2. `acceptance.acceptanceReachedAt` is set — every required GTT slug has reached `active`.
  3. The tx pays the buyer-declared seller wallet and the platform wallet — no third-party siphon.
  4. The datum's `template_hash` matches the purchase's recorded manifest hash — no hash drift between lock time and release time.

Refund rules

The refund path is unilateral — buyer-only. The platform cannot block, delay, or intermediate it.

  • The tx is signed by the buyer alone.
  • The validity range's lower bound is at or after `validation_deadline` (enforced on-chain).
  • The full locked amount returns to the buyer's address.
If this platform vanishes tomorrow, every locked purchase can still be reclaimed by its buyer after the deadline. That's a property of the validator, not of the platform.

Template anonymization

Templates are whitelisted exports of a workspace — every collection is filtered against a collection-sharp allow-schema, and a pattern verifier blocks PII leaks before publish. No allow-list, no publish.

  • Allow-schemas live in `src/lib/server/template-export/schemas.ts` — one per collection, hand-written, no common defaults.
  • The pattern verifier scans every emitted manifest for emails, wallet addresses, database ids, JWTs, UUIDs, phone numbers, and API-key signatures.
  • User ids are remapped deterministically to role placeholders (`role:responsible_1`) inside the manifest. The placeholder map itself is never exported.
  • Creator identity is opt-in only. Default is fully anonymous.

Platform disclosures

Platform fee

The platform takes a fixed percentage of the sale price, set per instance via `MARKETPLACE_PLATFORM_FEE_BPS`. The rate is embedded in the on-chain Datum at lock time — you see exactly what you're paying before you sign.

The platform as co-signer

The platform holds an Ed25519 key whose public key hash is embedded in every lock Datum. This key is held in an operator-managed secret store. It can only co-sign a Release — it cannot refund, cannot withdraw, cannot modify the Datum.

Why the platform can't game the system

Release requires the buyer's signature. The platform cannot pay itself without your consent. Refund requires the deadline. The platform cannot delay your refund past that. These are not policies — they are on-chain invariants.