rob thijssen 99483d90ca feat: rename to the qapi console, and deploy it to oolon
The console is now **qapi console**, served at https://qapi.blackbeard.observer.
The papi logo and the upstream licence stay: this is a fork of
polkadot-api/papi-console, not a rewrite, and the sidebar link points at our
fork rather than theirs.

Deployment follows architecture/deployment-gitea-actions.md — the workflow is
the source of infra truth, and one-time host provisioning is an operator script:

  script/infra-setup.sh   dns  -> the Cloudflare CNAME to bl.thgttg.com
                          cert -> Let's Encrypt, DNS-01, ECDSA
                          edge -> gitea_ci, scoped sudoers, webroot, vhosts

  .gitea/workflows/deploy.yaml   build (pnpm) -> rsync the bundle -> reload

The roles run in that order because certbot uses a DNS-01 challenge and nginx
fails its config test on a missing ssl_certificate — which would block every
reload on a SHARED proxy, not just this vhost. The same reasoning bounds what CI
may do: the sudoers drop-in grants rsync into one webroot, restorecon on it,
a config test and a reload. No certbot, no /etc/letsencrypt, no sites-available
write, no useradd.

Two vhosts, per architecture/reverse-proxies.md: the public one on the https
tier at 127.0.0.1:14443 behind the stream SNI router that owns TCP 443 (binding
443 directly is undetectable by `nginx -t` and ends with nginx silently serving
stale certificates), and a qapi.internal one for mesh clients, which stays
disabled until someone mints its internal certificate.

There is no application host and no upstream: the console is a static SPA that
opens WebSockets straight from the browser to the chains' own RPC endpoints.

The build gate is `pnpm build` (tsc -b + vite build) plus a check that the
signers-common patch is applied to the copy node actually resolves. Without that
patch every signing attempt dies with `Unkown signer` in a browser, after
deploy, in front of a user — and a lockfile drift is all it would take.

`pnpm lint` is deliberately not in the gate: it is broken upstream and was
before this fork touched anything (typescript-eslint 8.69 refuses to load
against the TypeScript 7.0 this repo resolves).

Live and verified: the public name answers 200 with this console's title over
the WAN address, serving the Let's Encrypt certificate for it, and the whole
deploy path — rsync as gitea_ci through the scoped sudoers, restorecon, config
test, reload, fetch — has been run by hand end to end.

Refs #3

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
2026-09-16 08:42:06 +03:00
2026-08-24 12:50:13 +02:00
2024-10-29 12:50:59 +01:00
WiP
2024-11-06 14:09:52 +01:00
2026-08-24 12:50:13 +02:00
2024-11-11 12:51:08 +07:00
2026-04-08 09:48:38 +02:00
2024-10-22 14:29:38 +02:00
2024-11-09 23:58:58 +07:00
2026-08-24 12:50:13 +02:00

qapi console

A fork of the papi console, pointed at the Quantus chains and patched to accept their post-quantum signature type.

Deployed at https://qapi.blackbeard.observer.

Why this fork exists

The console is built on polkadot-api, which shares no code with the polkadot-js stack the Quantus browser extension forks (quantus/extension, quantus/common, quantus/ui, quantus/wasm). That makes it an independent implementation of the same wire format — and the only way to find out whether our stack is right about Quantus or merely self-consistent.

It already is: for the same call, nonce and signature, createV4Tx here produces bytes identical to quantus/extension's tier-1 harness.

The one patch

getSignerType in @polkadot-api/signers-common reads the extrinsic's Address and Signature types out of the metadata — the right thing, and better than polkadot-js, which hardcodes ExtrinsicSignature: 'MultiSignature' in a type definition file. It then threw that answer away and required the enum to carry Ecdsa, Ed25519 and Sr25519.

Quantus's DilithiumSignatureScheme carries Dilithium87 and Dilithium65, so every signing attempt raised Unkown signer before reaching code that would have worked — createV4Tx is entirely length-agnostic, and a 7 219-byte ML-DSA-87 signature drops straight in.

patches/@polkadot-api__signers-common.patch drops the names and keeps the structural check. See quantus/papi-console#1.

Develop

pnpm install
pnpm dev

Deploy

Pushes to main deploy to oolon via .gitea/workflows/deploy.yaml. One-time host provisioning — DNS, certificate, nginx vhost, webroot — is script/infra-setup.sh, run by an operator:

./script/infra-setup.sh --pubkey ~/.ssh/id_gitea_ci.pub

Conventions: architecture/deployment-gitea-actions.md, reverse-proxies.md, external-tls.md, public-dns.md.


Upstream's own README, and the licence, are unchanged: this is a fork, not a rewrite.

Description
Fork of polkadot-api/papi-console (AGPL-3.0). A dev console for signing real Quantus extrinsics from the browser extension. Built on polkadot-api, which reads the extrinsic's Address and Signature types from metadata and assembles signed extrinsics length-agnostically — so it needs one patch, not a fork chain, and gives an independent check on the polkadot-js side.
https://qapi.blackbeard.observer
Readme AGPL-3.0 3.5 MiB
Languages
TypeScript 96.4%
Shell 2.4%
CSS 0.9%
JavaScript 0.2%