Thebes IDE ← back to the editor

Developer guide

You write an app. Thebes runs it on a Byzantine quorum, forever, with no servers. That is the entire mental model — the substrate's machinery (consensus, replication, post-quantum signatures) does its work without ever appearing in your code.

1 · The five-minute loop

  1. Start from a template or a description. Open templates (counter, guestbook, to-do, storefront) and pick one, or hit ✨ new dapp and describe what you want — the engineer writes the backend smart contract + frontend into your project. The tree also holds production-audited examples; each embeds the standard lib/Admin surface (ownership, admin tier, emergency pause), and the identity-aware ones wire lib/MemphisAuth (passkey sign-in).
  2. Ask the engineer. The feed on the right talks to the in-house model. It drafts, repairs, and verifies code against the real moc compiler server-side — an emitted file has, by construction, already compiled. Every tool step shows as a row you can expand; nothing runs invisibly. (Bring your own model with the ai ⚙ control if you prefer.)
  3. Check as you edit. check (or Ctrl+Enter) runs moc --check on the active buffer with the standard library resolved — full static type-checking in about a second, errors verbatim from the compiler.
  4. Deploy. deploy dapp ▸ compiles the backend + wires the frontend and hands back a live /_/raw/<id>/… URL — one click, in the browser, no terminal. Toggle demo 1h for a free, ephemeral contract that auto-deletes after an hour. Real deploys draw from your credit pool — sign in once with log in to deploy.

2 · Auth in six lines — the only two ideas

Operator auth (who administers the app) keys on the transport sender:

import Admin "lib/Admin";
persistent actor MyApp {
  var admin = Admin.init();                       // one stable var
  public shared(msg) func claimOwner() : async Bool { Admin.claimOwner(admin, msg.caller) };
  // guard any privileged method with one line:
  //   Admin.requireOwner(admin, msg.caller);  or requireAdmin / requireNotPaused
}

User auth (who is signed in) keys on a Memphis passkey session:

import MemphisAuth "lib/MemphisAuth";
persistent actor MyApp {
  var gate = MemphisAuth.initFromCid(921, "https://my-app-origin", 1);
  public shared(_msg) func myMethod(token : Blob) : async () {
    switch (await MemphisAuth.verify(gate, token)) {
      case (#ok(id)) { /* key your state on id.principal */ };
      case (#err(_)) { /* signed out / expired */ };
    };
  };
}

The user signs in once with a passkey (no passwords, no wallet), your app receives a stable per-app principal, and the same passkey works across every Thebes app without apps being able to track users across each other. Your smart contract asks Memphis directly, on-chain — no off-chain party can forge the answer.

3 · Frontend development

A Thebes app's frontend is plain static files (HTML/CSS/JS) served by the same smart contract — no build chain required, though you can bring one.

4 · Static checking — what the gates guarantee

GateWhenWhat it proves
moc --checkthe check button / Ctrl+Enterthe buffer type-checks against mo:core + lib/
engineer emit gateevery agent turnthe model cannot hand you code that does not compile
runtime smokebefore an example shipsthe deployed smart contract enforces its auth + accounting on a live chain

Trust the rows in the feed: a ✗ check block means the compiler rejected a draft and the engineer is repairing it — that loop is the feature.

5 · Status bar

model in use · tokens this session · active file · gateway endpoint (green dot = the engineer is reachable) · ai ⚙ (point the chat at your own model) · your sign-in + credit balance. The gateway field is editable — point it at your own endpoint if you self-host.