Skip to content

Commit 613c18f

Browse files
authored
Merge branch 'main' into fix/cut-version-no-bump
2 parents b3d056d + 79eba39 commit 613c18f

62 files changed

Lines changed: 1636 additions & 2042 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy-playground.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ on:
88
environment:
99
description: bulletin-deploy environment to publish to (blank = CLI default)
1010
type: choice
11-
default: ''
11+
default: ""
1212
options:
13-
- ''
13+
- ""
1414
- paseo-next-v2
1515
- preview
1616
- paseo-next
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Diagnosis report
2+
3+
# A diagnosis run in the playground files a pre-filled issue (labeled
4+
# `diagnosis-report`) carrying the markdown report in its body. This workflow
5+
# turns that issue into a PR that adds/updates the host's report under
6+
# explorer/diagnosis-reports/. The compatibility matrix is a build artifact
7+
# regenerated from those reports, so the PR only touches the report file.
8+
9+
on:
10+
issues:
11+
types: [labeled]
12+
13+
# Serialize so concurrent submissions never race on a branch push.
14+
concurrency:
15+
group: diagnosis-report
16+
cancel-in-progress: false
17+
18+
permissions:
19+
contents: write
20+
pull-requests: write
21+
issues: write
22+
23+
jobs:
24+
ingest:
25+
if: github.event.label.name == 'diagnosis-report'
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- name: Build the report PR
31+
env:
32+
GH_TOKEN: ${{ github.token }}
33+
BODY: ${{ github.event.issue.body }}
34+
ISSUE: ${{ github.event.issue.number }}
35+
run: |
36+
set -euo pipefail
37+
38+
# Host mode from the report title (`## Truapi <mode> Diagnosis`).
39+
mode=$(printf '%s' "$BODY" \
40+
| grep -ioP '##\s+Truapi\s+\K(Web|Desktop|Android|iOS)(?=\s+Diagnosis)' \
41+
| head -1 || true)
42+
if [ -z "$mode" ]; then
43+
gh issue comment "$ISSUE" --body \
44+
"Could not read a host from this report (expected a \`## Truapi <Web|Desktop|Android|iOS> Diagnosis\` heading). Not filing a PR."
45+
exit 1
46+
fi
47+
host=$(printf '%s' "$mode" | tr '[:upper:]' '[:lower:]')
48+
branch="diagnosis-report/$host"
49+
file="explorer/diagnosis-reports/$host.md"
50+
51+
git fetch origin main
52+
git switch -C "$branch" origin/main
53+
printf '%s\n' "$BODY" > "$file"
54+
55+
git config user.name "github-actions[bot]"
56+
git config user.email "github-actions[bot]@users.noreply.github.com"
57+
if git diff --quiet -- "$file"; then
58+
gh issue comment "$ISSUE" --body \
59+
"This $mode report matches the current \`$file\`; nothing to update."
60+
gh issue close "$ISSUE"
61+
exit 0
62+
fi
63+
git add "$file"
64+
git commit -m "diagnosis: update $host report (from #$ISSUE)"
65+
git push -f origin "$branch"
66+
67+
# One PR per host branch: open it the first time, reuse it after.
68+
url=$(gh pr view "$branch" --json url --jq .url 2>/dev/null || true)
69+
if [ -z "$url" ]; then
70+
url=$(gh pr create --base main --head "$branch" \
71+
--title "diagnosis: $mode host report" \
72+
--body "Updates \`$file\` from the playground Diagnosis. The compatibility matrix is regenerated from the reports at build time.")
73+
fi
74+
75+
gh issue comment "$ISSUE" --body "Filed in $url"
76+
gh issue close "$ISSUE"

Makefile

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@
33
# Run `make help` for the list of targets.
44

55
.DEFAULT_GOAL := help
6-
.PHONY: help setup build codegen test check playground
6+
.PHONY: help setup build codegen test check playground dev matrix explorer
77

88
TRUAPI_PKG := js/packages/truapi
99
PLAYGROUND := playground
10+
EXPLORER := explorer
11+
DOTLI := hosts/dotli
12+
13+
# `make dev DEBUG=1` runs dotli with VITE_APP_DEBUG=true to log every wire frame.
14+
DOTLI_PREVIEW := preview
15+
ifdef DEBUG
16+
DOTLI_PREVIEW := preview:debug
17+
endif
1018

1119
help: ## Show this help.
1220
@awk 'BEGIN { FS = ":.*##"; printf "Usage: make <target>\n\nTargets:\n" } \
@@ -41,3 +49,15 @@ playground: ## Refresh the playground's @parity/truapi snapshot and rebuild.
4149
cd $(TRUAPI_PKG) && npm run build
4250
cd $(PLAYGROUND) && rm -rf node_modules/@parity && yarn install
4351
cd $(PLAYGROUND) && yarn build
52+
53+
dev: ## Start dotli host (:5173) + playground (:3000) together; open http://localhost:5173/localhost:3000. DEBUG=1 logs wire frames.
54+
@trap 'kill 0' EXIT; \
55+
( cd $(DOTLI) && bun run $(DOTLI_PREVIEW) ) & \
56+
( cd $(PLAYGROUND) && yarn dev ) & \
57+
wait
58+
59+
matrix: ## Regenerate the host compatibility matrix from explorer/diagnosis-reports.
60+
cd $(EXPLORER) && npm run generate-matrix
61+
62+
explorer: ## Run the explorer dev server standalone at http://localhost:5181.
63+
cd $(EXPLORER) && npx vite --base / --port 5181

docs/rfcs/extended-theme-api.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
title: "Extended theme subscribe API"
3+
owner: "@filippovecchiato"
4+
---
5+
6+
# RFC — Extended theme subscribe API
7+
8+
| | |
9+
| --------------- | ---------------------------------------------------------------- |
10+
| **Start Date** | 2026-06-01 |
11+
| **Description** | Replace the bare light/dark enum with a structured theme payload carrying a name and variant. |
12+
| **Authors** | Filippo Vecchiato |
13+
14+
## Summary
15+
16+
Extend `HostThemeSubscribeItem` so the host can tell a product **which** theme to apply, not just whether to use light or dark mode. The subscription delivers a structured value with a theme name and a light/dark variant.
17+
18+
## Motivation
19+
20+
Upstream: [triangle-js-sdks#191](https://github.com/paritytech/triangle-js-sdks/pull/191)
21+
22+
The current `Theme` enum only carries `Light` or `Dark`. Products cannot distinguish named host themes.
23+
24+
## Detailed Design
25+
26+
Replace the existing `Theme` enum with two types:
27+
28+
```rust
29+
/// Identifies a named theme.
30+
enum ThemeName {
31+
/// A custom named theme.
32+
Custom(String),
33+
/// The host's default theme.
34+
Default,
35+
}
36+
37+
/// Light or dark variant.
38+
enum ThemeVariant {
39+
Light,
40+
Dark,
41+
}
42+
```
43+
44+
Update `HostThemeSubscribeItem` to carry both:
45+
46+
```rust
47+
struct HostThemeSubscribeItem {
48+
/// Theme name.
49+
pub name: ThemeName,
50+
/// Light or dark variant.
51+
pub variant: ThemeVariant,
52+
}
53+
```
54+
55+
The old `Theme` enum (`Light | Dark`) is renamed to `ThemeVariant` for clarity. SCALE codec indices are unchanged — `ThemeVariant::Light` is still index 0, `ThemeVariant::Dark` is still index 1.
56+
57+
`HostThemeSubscribeItem` changes shape (gains a `name` field, `theme: Theme` becomes `variant: ThemeVariant`), so this is a wire-breaking change within v0.1. Host and product must be on matching versions.
58+
59+
## Drawbacks
60+
61+
- Wire-breaking change: deployed products on the old schema will fail to decode the new payload until updated.
62+

docs/rfcs/payment-topup-sr25519.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
title: "Use Sr25519 Secret Keys in PaymentTopUpSource"
3+
owner: "@filippovecchiato"
4+
---
5+
6+
# RFC — Use Sr25519 Secret Keys in PaymentTopUpSource
7+
8+
## Summary
9+
10+
Change all secret key fields in `PaymentTopUpSource` (RFC 0006) from 32-byte keys to 64-byte Sr25519 secret keys. The `PrivateKey` variant switches from `Ed25519PrivateKey` to `Sr25519SecretKey`, and the `Coins` variant widens its keys to match.
11+
12+
## Motivation
13+
14+
RFC 0006 specified Ed25519 for the `PrivateKey` variant, but the host implementation in triangle-js-sdks uses Sr25519 ([triangle-js-sdks#198](https://github.com/paritytech/triangle-js-sdks/pull/198)). The original RFC was simply wrong at that place — the accounts backing top-ups are Sr25519, not Ed25519. The `Coins` variant already used Sr25519, but with a 32-byte mini-secret; the upstream implementation uses the full 64-byte secret key for both.
15+
16+
## Detailed Design
17+
18+
`PaymentTopUpSource` changes from:
19+
20+
```rust
21+
enum PaymentTopUpSource {
22+
ProductAccount { derivation_index: u32 },
23+
PrivateKey { ed25519_private_key: [u8; 32] },
24+
Coins { sr25519_secret_keys: Vec<[u8; 32]> },
25+
}
26+
```
27+
28+
to:
29+
30+
```rust
31+
enum PaymentTopUpSource {
32+
ProductAccount { derivation_index: u32 },
33+
PrivateKey { sr25519_secret_key: [u8; 64] },
34+
Coins { sr25519_secret_keys: Vec<[u8; 64]> },
35+
}
36+
```
37+
38+
Both `PrivateKey` and `Coins` now carry 64-byte Sr25519 secret keys. The `Ed25519PrivateKey` type is removed.
39+
40+
This is a **wire-breaking** change: the SCALE encoding of both variants changes length. All hosts and products must upgrade together within the same protocol version.

explorer/.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@ dist
44
.vite
55
.DS_Store
66

7-
# Diagnosis reports waiting to be aggregated. The aggregated source-of-truth
8-
# at src/data/compatibility.ts is committed; the per-host inputs are not.
9-
pending-reports/*.md
7+
# Generated at build/dev time from diagnosis-reports/ (see scripts/aggregate-diagnosis-matrix.mjs).
8+
src/data/compatibility.ts

explorer/README.md

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,29 @@ Docs-only browser for the TrUAPI service surface. All trait and type data is sou
44

55
## Host compatibility matrix
66

7-
The **Compatibility** page (`/v/<version>/compatibility`) renders a host × method matrix aggregated from the playground's per-host Diagnosis reports. The matrix data is committed at [`src/data/compatibility.ts`](src/data/compatibility.ts) a typed module emitted by [`scripts/aggregate-diagnosis-matrix.mjs`](scripts/aggregate-diagnosis-matrix.mjs). It is the **only** runtime-derived data in the explorer; everything else flows from Rust via codegen.
7+
The **Compatibility** page (`/v/<version>/compatibility`) renders a host × method matrix aggregated from the playground's per-host Diagnosis reports. The committed per-host reports under [`diagnosis-reports/`](diagnosis-reports/) are the source of truth; [`src/data/compatibility.ts`](src/data/compatibility.ts) is a generated artifact (git-ignored) that [`scripts/aggregate-diagnosis-matrix.mjs`](scripts/aggregate-diagnosis-matrix.mjs) rebuilds from those reports at `dev` / `build` / `lint` time (via the `predev` / `prebuild` / `prelint` scripts). It is the **only** runtime-derived data in the explorer; everything else flows from Rust via codegen.
88

99
### Updating the matrix
1010

11-
1. **Collect reports.** For each host you want covered, open the playground in that host, run the Diagnosis, and click **Copy report** (see [`../playground/README.md#diagnosis`](../playground/README.md#diagnosis)). Save each report to a host-named markdown file (e.g. `web.md`, `desktop.md`).
12-
2. **Drop them in.** Place every `*.md` into [`pending-reports/`](pending-reports/).
13-
3. **Regenerate.** From the `explorer/` directory:
11+
Because the matrix is regenerated from `diagnosis-reports/` on every `dev` / `build` / `lint`, you only ever commit reports, never `src/data/compatibility.ts`.
1412

15-
```bash
16-
npm run generate-matrix
17-
```
13+
**From the playground (recommended).** Open the playground in the host you want to (re)measure, run the Diagnosis, and click **Submit report ↗**. That files a pre-filled `diagnosis-report` issue; the [`diagnosis-report`](../.github/workflows/diagnosis-report.yml) workflow writes the report to `diagnosis-reports/<host>.md` and opens (or updates) that host's PR.
1814

19-
That rewrites `src/data/compatibility.ts` from the reports and deletes the consumed inputs from `pending-reports/`. The Compatibility page (and each method's Host support row) picks up the new data on the next build / Vite HMR.
20-
4. **Commit** the updated `src/data/compatibility.ts` so the published matrix reflects the new run. The reports themselves are gitignored — only the aggregate is checked in.
15+
**By hand.** Click **Copy report** instead (see [`../playground/README.md#diagnosis`](../playground/README.md#diagnosis)), save the markdown to a host-named file (e.g. `web.md`, `desktop.md`, `android.md`, `ios.md`), drop it into [`diagnosis-reports/`](diagnosis-reports/) overwriting that host's previous report, and commit. Run `npm run generate-matrix` from `explorer/` to preview locally (or just `npm run dev`, which regenerates first). The Compatibility page and each method's Host support row pick up the new data on the next build / Vite HMR.
2116

2217
### Data shape
2318

24-
[`src/data/compatibility-types.ts`](src/data/compatibility-types.ts) holds the schema. Each method row carries one `pass | fail | null` entry per host column; `null` means the method was absent from that host's report (typically a method added after the report was taken). Columns are labelled by host mode (`Web` / `Desktop`); when two reports share a mode, the filename disambiguates the label.
19+
[`src/data/compatibility-types.ts`](src/data/compatibility-types.ts) holds the schema. Each method row carries one `pass | fail | null` entry per host column; `null` means the method was absent from (or skipped in) that host's report. Methods with no measurement on any host are dropped from the matrix. Columns are labelled by host mode (`Web` / `Desktop` / `Android` / `iOS`); when two reports share a mode, the filename disambiguates the label.
2520

2621
### Standalone CLI
2722

2823
The aggregator can be invoked directly:
2924

3025
```bash
3126
node scripts/aggregate-diagnosis-matrix.mjs web.md desktop.md # markdown preview to stdout
32-
node scripts/aggregate-diagnosis-matrix.mjs --explorer-out src/data/compatibility.ts --consume pending-reports
27+
node scripts/aggregate-diagnosis-matrix.mjs --explorer-out src/data/compatibility.ts diagnosis-reports
3328
```
3429

3530
Flags:
3631

3732
- `--explorer-out <file>` — write the TypeScript matrix module instead of stdout markdown.
38-
- `--consume` — delete the input report files **after** a successful write.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
## Truapi Android Diagnosis
2+
3+
| Method | Status | Details |
4+
| --- | --- | --- |
5+
| `Account/connection_status_subscribe` || |
6+
| `Account/get_account` || |
7+
| `Account/get_account_alias` || |
8+
| `Account/create_account_proof` || createAccountProof failed: { "error": { "tag": "Unknown", "value": { "reason": "Not implemented" } } } |
9+
| `Account/get_legacy_accounts` || |
10+
| `Account/get_user_id` || getUserId failed: { "error": { "tag": "Unknown", "value": { "reason": "Not implemented" } } } |
11+
| `Account/request_login` || |
12+
| `Chain/follow_head_subscribe` || |
13+
| `Chain/get_head_header` || |
14+
| `Chain/get_head_body` || |
15+
| `Chain/get_head_storage` || |
16+
| `Chain/call_head` || |
17+
| `Chain/unpin_head` || |
18+
| `Chain/continue_head` || |
19+
| `Chain/stop_head_operation` || |
20+
| `Chain/get_spec_genesis_hash` || |
21+
| `Chain/get_spec_chain_name` || |
22+
| `Chain/get_spec_properties` || |
23+
| `Chain/broadcast_transaction` || |
24+
| `Chain/stop_transaction` || |
25+
| `Chat/create_room` || timed out after 10s |
26+
| `Chat/register_bot` || registerBot failed: { "error": { "tag": "Unknown", "value": { "reason": "Not implemented" } } } |
27+
| `Chat/list_subscribe` || timed out after 10s |
28+
| `Chat/post_message` || postMessage failed: { "error": { "tag": "Unknown", "value": { "reason": "Error: Unknown method: chatSendTextMessage" } } } |
29+
| `Chat/action_subscribe` || timed out after 10s |
30+
| `Chat/custom_message_render_subscribe` || timed out after 10s |
31+
| `Entropy/derive` || |
32+
| `Local Storage/read` || |
33+
| `Local Storage/write` || |
34+
| `Local Storage/clear` || |
35+
| `Notifications/send_push_notification` || |
36+
| `Notifications/cancel_push_notification` || |
37+
| `Payment/balance_subscribe` || |
38+
| `Payment/top_up` || |
39+
| `Payment/request` || |
40+
| `Payment/status_subscribe` || |
41+
| `Permissions/request_device_permission` || |
42+
| `Permissions/request_remote_permission` || |
43+
| `Preimage/lookup_subscribe` || |
44+
| `Preimage/submit` || |
45+
| `Resource Allocation/request` || |
46+
| `Signing/create_transaction` || createTransaction failed: { "error": { "tag": "Unknown", "value": { "reason": "Error: Internal error: User rejected" } } } |
47+
| `Signing/create_transaction_with_legacy_account` || createTransactionWithLegacyAccount failed: { "error": { "tag": "Unknown", "value": { "reason": "Not implemented" } } } |
48+
| `Signing/sign_raw_with_legacy_account` || signRawWithLegacyAccount failed: { "error": { "tag": "Unknown", "value": { "reason": "Not implemented" } } } |
49+
| `Signing/sign_payload_with_legacy_account` || signPayloadWithLegacyAccount failed: { "error": { "tag": "Unknown", "value": { "reason": "Not implemented" } } } |
50+
| `Signing/sign_raw` || |
51+
| `Signing/sign_payload` || |
52+
| `Statement Store/subscribe` || submitting proof: { "tag": "Sr25519", "value": { "signature": "0x787cd296d80ffd9f0ed27c0fc727e12e0f1dbb70003ec490677ad59f3104350496c08caf27d2e4eb197967ec5be9c13703e09e731285d99e9c2d3b9df63c148b", "signer": "0xf601e46c084b558a21a979321f96f61c011f119b67ad30269b58234c3e47553a" } } proof submitted: timed out after 10s |
53+
| `Statement Store/create_proof` || |
54+
| `Statement Store/submit` || |
55+
| `Statement Store/create_proof_authorized` || |
56+
| `System/handshake` || |
57+
| `System/feature_supported` || |
58+
| `System/navigate_to` || |
59+
| `Theme/subscribe` || |

0 commit comments

Comments
 (0)