Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ release/
dist/
cache/

### Astro (branch residue) ###
### Astro ###
.astro/
49 changes: 22 additions & 27 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,49 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project

VitePress documentation site for the **did:btcr2** DID Method (Bitcoin Reference 2.0), a censorship-resistant DID method anchored to the Bitcoin blockchain. Deployed to `btcr2.dev`.
Astro Starlight documentation site for the **did:btcr2** DID Method (Bitcoin Reference 2.0), a censorship-resistant DID method anchored to the Bitcoin blockchain. Deployed to `btcr2.dev`.

## Commands

Package manager: **pnpm 10.16.1** (declared in `packageManager`). Use `pnpm`, not `npm` or `yarn`.

- `pnpm dev`: VitePress dev server (`vitepress dev docs`)
- `pnpm build`: Production build (`vitepress build docs`, output goes to `docs/.vitepress/dist`)
- `pnpm typecheck`: `vue-tsc --noEmit` against `docs/.vitepress/tsconfig.json`
- `pnpm preview`: Serve build on port 8080
- `pnpm serve`: `vitepress serve docs`
- `pnpm clean`: Wipe `node_modules`, lockfile, and VitePress cache/dist
- `pnpm dev`: Astro dev server
- `pnpm build`: Production build (output goes to `dist/`)
- `pnpm typecheck`: `astro check` (also validates the TS example snippets in `src/examples/`)
- `pnpm preview`: Serve the build locally
- `pnpm clean`: Wipe `node_modules`, lockfile, `.astro`, and `dist`

There is no test or lint script. Run `pnpm typecheck && pnpm build` before committing theme/demo changes.
Run `pnpm typecheck && pnpm build` before committing. No lockfile is committed (`.gitignore`d by design), so installs float on latest matching versions.

## Architecture

### Content lives in `docs/`
- Markdown pages: `docs/index.md` (home), `docs/spec.md`, `docs/demo.md`, `docs/diagrams.md`, `docs/impls.md`, `docs/parity.md`, plus per-language pages under `docs/impls/{java,py,rs,ts}.md`.
- TypeScript code snippets embedded in `docs/impls/ts.md` via `<<< @/examples/ts/*.ts` live in `docs/examples/ts/`.
- VitePress nav/sidebar/theme config: `docs/.vitepress/config.ts`.
### Content lives in `src/content/docs/`
- Pages: `index.mdx` (splash home), `spec.md`, `demo.mdx`, `diagrams.md`, `parity.md`, `impls.md`, and `impls/{java,py,rs}.md` + `impls/ts.mdx`.
- Starlight requires a `title` in every page's frontmatter; do not add an H1 in the body.
- `.mdx` pages import components explicitly; `.md` pages are plain markdown. MDX does NOT support `<https://url>` autolinks; use `[text](url)`.
- TS example snippets live in `src/examples/ts/` and are embedded in `impls/ts.mdx` via `?raw` imports + Starlight's `<Code>` component. They are typechecked by `astro check`, so they must be self-contained.
- Nav/sidebar/theme config: `astro.config.mjs` (Starlight `sidebar`, `social`, `customCss`).

### Custom theme + Vue demo components
`docs/.vitepress/theme/index.ts` extends the default VitePress theme and globally registers:
- `<DemoCreate />`, `<DemoResolve />`, `<DemoUpdate />` (also `<DemoUpdate op="deactivate" />`) from `theme/demos/`, used inline in `demo.md`.
- `<DemoCard>` (shared demo shell) and `<Mermaid>` from `theme/components/`.
### Interactive demos (Vue islands)
Vue 3 demo components live in `src/theme/` (`components/`, `demos/`, `composables/`) and are mounted in `demo.mdx` as islands with `client:only="vue"`; they never render during SSR. `composables/useDidBtcr2.ts` dynamically imports `@did-btcr2/api`, `@did-btcr2/keypair`, and `@did-btcr2/common` once per page and exposes `createApiForNetwork()`. The packages are pure JS (no WASM). Keep new `@did-btcr2/*` usage behind the composable.

`theme/composables/useDidBtcr2.ts` dynamically imports `@did-btcr2/api`, `@did-btcr2/keypair`, and `@did-btcr2/common` once per page and exposes `createApiForNetwork()`. The dynamic import keeps these packages out of VitePress SSR; the demos are strictly client-side. The packages are pure JS (no WASM), so no WASM/top-level-await Vite plugins are needed. Keep new `@did-btcr2/*` usage behind the composable.
The components still use `--vp-c-*` CSS variables from their VitePress origin; `src/styles/custom.css` aliases those to Starlight's `--sl-color-*` palette. Don't remove the alias block.

### Mermaid diagrams
A markdown-it fence override in `config.ts` turns ```` ```mermaid ```` blocks into `<Mermaid code-b64="...">`; `Mermaid.vue` renders client-side in `onMounted` (theme-aware, re-renders on dark-mode toggle). There is no vitepress mermaid plugin; diagram sources live inline in the markdown pages.
```` ```mermaid ```` fences render client-side via the `astro-mermaid` integration (registered BEFORE `starlight` in `astro.config.mjs`; order matters). Theme switching is automatic. Diagram sources live inline in the markdown pages; standalone OKR sources are kept in `public/diagrams/okrs/`.

### Bitcoin REST endpoints (same-origin /mempool proxy is REQUIRED)
mempool.space networks (`bitcoin`, `testnet3`, `testnet4`, `signet`) are routed through the site's **same-origin `/mempool` path** via `createApiForNetwork()` in `useDidBtcr2.ts`:
- Dev: the Vite `server.proxy` block in `config.ts`.
mempool.space networks (`bitcoin`, `testnet3`, `testnet4`, `signet`) are routed through the site's **same-origin `/mempool` path** via `createApiForNetwork()` in `src/theme/composables/useDidBtcr2.ts`:
- Dev: the `vite.server.proxy` block in `astro.config.mjs`.
- Prod: the VM's nginx `location /mempool/ { proxy_pass https://mempool.space/; }` block (added via helpdesk issue #25; not in this repo).

Direct browser calls to mempool.space FAIL: `@did-btcr2/bitcoin`'s REST client sends `Content-Type: application/json` on GETs, making them non-simple requests, and mempool.space's OPTIONS handler 404s the resulting preflight. Do not "simplify" this back to direct calls unless the upstream client stops sending that header. `mutinynet.com` handles preflight correctly and stays direct; `regtest` uses the library's localhost default. There is no `fetch` monkey-patching and no env-var config; the `@did-btcr2` packages take explicit config objects only (`createApi({ btc: { network, rest, rpc, executor } })`).

### Deployment
btcr2.dev is served from a company VM with **no automation**. Release flow: bump `Version:` in `rpm/btcr2-dev.spec` (+ changelog) and `package.json`, push to the GitLab upstream (`gl1.dcdpr.com:website/btcr2-dev.git`), tag `vX.Y.Z`, then file an issue on the internal helpdesk GitLab; third-party IT clones the GitLab repo at the tag, builds an RPM (`rpmbuild -ta`, spec runs `npm install && npm run build` and installs `docs/.vitepress/dist/*` to `/var/www/btcr2-dev`), and installs it. nginx serves the site and must keep the `/mempool` proxy block. The GitHub Actions workflow in `.github/workflows/ci.yml` only verifies typecheck+build (weekly cron catches upstream `@did-btcr2` breakage, since no lockfile is committed); it does not deploy.

### Vite resolve settings
`config.ts` sets `resolve.conditions: ['browser']` (so the `@did-btcr2/*` prebuilt browser bundles are picked up during SSR/build) and `resolve.dedupe: ['vue']`. Keep these when adding packages with Node-vs-browser conditional exports.
btcr2.dev is served from a company VM with **no automation**. Release flow: bump `Version:` in `rpm/btcr2-dev.spec` (+ changelog) and `package.json`, push to the GitLab upstream (`gl1.dcdpr.com:website/btcr2-dev.git`), tag `vX.Y.Z`, then file an issue on the internal helpdesk GitLab; third-party IT clones the GitLab repo at the tag, builds an RPM (`rpmbuild -ta`, spec runs `npm install && npm run build` and installs `dist/*` to `/var/www/btcr2-dev`), and installs it. nginx serves the site and must keep the `/mempool` proxy block. The GitHub Actions workflow in `.github/workflows/ci.yml` only verifies typecheck+build (weekly cron catches upstream `@did-btcr2` breakage, since no lockfile is committed); it does not deploy.

## Conventions

- License: **MPL-2.0**.
- Markdown pages can embed the registered Vue components directly as tags; no per-page imports needed.
- Dependency versions track the `did-btcr2-js` monorepo (`@did-btcr2/api` / `keypair` / `common`); when bumping, re-run the demos against a test network. The api facade is pre-1.0 and moves fast.
- The spec itself is **not** in this repo. `docs/spec.md` only links to `https://dcdpr.github.io/did-btcr2` (source: `github.com/dcdpr/did-btcr2`). Don't try to edit spec content here.
- Dependency versions track the `did-btcr2-js` monorepo (`@did-btcr2/api` / `keypair` / `common`); the api facade is pre-1.0 and moves fast. When bumping, re-run the demos against a test network.
- The spec itself is **not** in this repo. `src/content/docs/spec.md` only links to `https://dcdpr.github.io/did-btcr2`. Don't try to edit spec content here.
55 changes: 55 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import vue from '@astrojs/vue';
import mermaid from 'astro-mermaid';

export default defineConfig({
site: 'https://btcr2.dev',
vite: {
server: {
// Dev-server twin of the production nginx `location /mempool/` block
// (see rpm/ and CLAUDE.md). Same-origin proxying is REQUIRED for
// mempool.space: the @did-btcr2/bitcoin REST client sends
// `Content-Type: application/json` on GETs, which triggers a CORS
// preflight that mempool.space's OPTIONS handler rejects (404).
proxy: {
'/mempool': {
target: 'https://mempool.space',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/mempool/, ''),
},
},
},
},
integrations: [
// astro-mermaid must come before starlight so its remark plugin sees the
// ```mermaid fences first.
mermaid({ autoTheme: true }),
starlight({
title: 'did:btcr2',
description:
'A censorship-resistant DID Method using the Bitcoin blockchain as a Verifiable Data Registry to announce changes to the DID document.',
social: [
{ icon: 'github', label: 'GitHub', href: 'https://github.com/dcdpr/did-btcr2' },
],
sidebar: [
{ label: 'Specification', link: '/spec/' },
{ label: 'Diagrams', link: '/diagrams/' },
{ label: 'Demo', link: '/demo/' },
{
label: 'Implementations',
items: [
{ label: 'Overview', link: '/impls/' },
{ label: 'Java', link: '/impls/java/' },
{ label: 'Python', link: '/impls/py/' },
{ label: 'Rust', link: '/impls/rs/' },
{ label: 'TypeScript', link: '/impls/ts/' },
],
},
{ label: 'Cross-impl Parity', link: '/parity/' },
],
customCss: ['./src/styles/custom.css'],
}),
vue(),
],
});
84 changes: 0 additions & 84 deletions docs/.vitepress/config.ts

This file was deleted.

18 changes: 0 additions & 18 deletions docs/.vitepress/shims.d.ts

This file was deleted.

118 changes: 0 additions & 118 deletions docs/.vitepress/theme/components/Mermaid.vue

This file was deleted.

Loading