Grow into a DAML security expert. An interactive, browser-based learning trail for spotting and fixing vulnerabilities in DAML smart contracts β from tiny Seedling to Ancient Tree.
No build step. No backend. Open index.html and start learning.
- 6 courses spanning beginner β advanced, with hands-on code challenges:
- π DAML Fundamentals
- π Authorization & Parties
- βοΈ Privacy & Divulgence
- βοΈ Value Conservation
- β±οΈ Time & Deadlines
- π Keys & Governance
- In-browser DAML editor powered by Monaco, with custom DAML syntax highlighting and pattern-based challenge validation (editor.js).
- Gamified progression β 6 growth ranks (Seedling β Sapling β Young Tree β Forest Guardian β Elder Tree β Ancient Tree) earned by fixing bugs and completing chapters (app.js).
- Standalone learning curriculum β 12 markdown lessons in learning/ covering the ledger model, choices, authorization, divulgence, UTXO conservation, time/skew, keys, Daml Script, interfaces, functional patterns, and governance/arithmetic. Start at learning/INDEX.md.
DamlForest is a fully static site β no build step, no backend, no package manager. Follow the steps below end-to-end.
Before you start, make sure you have:
- A modern browser β Chrome, Firefox, Safari, or Edge (latest versions).
- Git β to clone the repo. Verify with
git --version. - One static HTTP server. Any of these works; pick what's already installed:
- Python 3 (ships with macOS and most Linux distros) β
python3 --version - Node.js 18+ β
node --version - PHP 7+ β
php --version - Docker β
docker --version
- Python 3 (ships with macOS and most Linux distros) β
- Internet access on first load. Monaco Editor is fetched from
cdnjs.cloudflare.com(index.html:349-351). Once the browser has cached it, later visits work offline.
Why a server? You can double-click
index.htmland it will partially work, but some browsers block CDN scripts and JS modules under thefile://origin. Serving overhttp://avoids that.
git clone <this-repo-url>
cd daml-forestConfirm the files are there:
ls
# expected: app.js courses.js editor.js index.html learning styles.css README.mdRun one of the commands below from inside daml-forest/. All of them serve the current directory on port 8000.
Option A β Python 3 (recommended, zero install on macOS/Linux)
python3 -m http.server 8000Option B β Node.js via npx (no global install needed)
npx --yes http-server -p 8000 -c-1 .
# -c-1 disables caching so edits show up on refreshOption C β PHP
php -S localhost:8000Option D β Docker (uses nginx, keeps your host clean)
docker run --rm -p 8000:80 -v "$PWD":/usr/share/nginx/html:ro nginx:alpineOption E β VS Code "Live Server" extension
- Install the Live Server extension (publisher: Ritwick Dey).
- Right-click
index.htmlin the Explorer pane. - Choose Open with Live Server. It picks its own port (usually 5500).
Leave the terminal running β stopping it (Ctrl+C) shuts the server down.
Visit http://localhost:8000 in your browser. You should see the green DamlForest hero. Click Enter the Forest to start.
If you used Docker or a different port, adjust the URL accordingly.
A correct install will show:
- β Hero page renders with an animated tree.
- β Clicking Trails lists 6 courses.
- β Opening any chapter loads the Monaco code editor with DAML syntax highlighting.
- β The Run / Check button validates your code against the chapter's required patterns.
If the editor area stays blank, open DevTools β Console and look for blocked requests to cdnjs.cloudflare.com β that's the CDN issue from the prerequisites.
All state is kept in localStorage under the key damlforest_state (app.js:160,164). Nothing leaves your browser. To wipe it:
// Paste into DevTools β Console
localStorage.removeItem("damlforest_state");
location.reload();| Symptom | Fix |
|---|---|
Address already in use on port 8000 |
lsof -i :8000 to find the culprit, or pick another port (e.g. python3 -m http.server 5173). |
| Editor area is blank | CDN blocked β check Console for failed requests to cdnjs.cloudflare.com; allow it in your adblocker / firewall. |
Changes to .js / .css don't show up |
Hard-reload (Cmd/Ctrl + Shift + R), or run http-server -c-1 to disable caching. |
python3: command not found |
Install Python 3, or use one of the other server options. |
Because the source is the deploy artifact, any static host works β GitHub Pages, Netlify, Vercel, Cloudflare Pages, S3 + CloudFront, Surge. Configuration:
- Build command: (none)
- Publish / output directory:
daml-forest/(or.if the repo root isdaml-forest/)
| Path | Purpose |
|---|---|
| index.html | Single-page app shell β hero, course grid, chapter view |
| styles.css | Forest-themed styling, animations, rank visuals |
| app.js | Navigation, rank progression, progress persistence, tree SVGs |
| courses.js | All course/chapter content: theory, tasks, starter code, solutions, validation patterns |
| editor.js | Monaco setup, DAML Monarch grammar, dark theme |
| learning/ | Standalone markdown curriculum (12 lessons + index) |
| # | Lesson | Level |
|---|---|---|
| 1 | Intro to DAML | Beginner |
| 2 | Choices | Beginner |
| 3 | Data Types & ensure |
Beginner |
| 4 | Parties & Authority | Beginner β Intermediate |
| 5 | Privacy & Divulgence | Intermediate |
| 6 | UTXO & Conservation | Intermediate |
| 7 | Time & Deadlines | Intermediate β Advanced |
| 8 | Keys & Contention | Advanced |
| 9 | Daml Script Testing | Advanced |
| 10 | Interfaces | Advanced |
| 11 | Functional Programming | Advanced |
| 12 | Governance & Arithmetic | Advanced |
See learning/INDEX.md for the full map, role-based learning paths, and the Top 10 DAML Security Checklist.
Every chapter lives as a plain JS object in courses.js:
{
id: "1-1",
title: "What is DAML?",
theory: `<h1>...</h1>`, // HTML shown in the chapter intro
task: "Add a signatory line ...", // one-sentence instruction
hint: "Use: signatory bank",
initialCode: `template ...`, // starter code in the editor
solution: `template ...`, // reference solution
requiredPatterns: ["signatory bank"], // substrings that must appear to pass
forbiddenPatterns: [] // substrings that must NOT appear
}Add a new entry to the relevant course's chapters array and reload. Progress is stored in localStorage.