Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
25b8940
Add dotli → TrUAPI migration notes
pgherveou Apr 30, 2026
b37641d
Add @truapi/* workspace deps + serve-from-monorepo
pgherveou Apr 30, 2026
266c218
Add host-callbacks/ adapters mirroring demo structure
pgherveou Apr 30, 2026
b28facf
Swap bridge.ts from setupContainer to createIframeHost
pgherveou Apr 30, 2026
680afed
Delete container.ts and statement-store-mapping.ts
pgherveou Apr 30, 2026
75098fe
Drop @novasamatech/{host-api,host-container,sdk-statement,statement-s…
pgherveou Apr 30, 2026
4d72901
fixes
pgherveou Apr 30, 2026
d0c7aaa
Drop @novasamatech/host-api type-level dep
pgherveou May 4, 2026
7182792
Switch dotli bridge to parity wasm host
pgherveou Jun 8, 2026
904c8f4
Add core pairing session callbacks
pgherveou Jun 8, 2026
42ebe7d
Add core operation host callbacks
pgherveou Jun 8, 2026
98d2d15
Remove legacy auth from ui login
pgherveou Jun 8, 2026
0ff0c50
Remove legacy auth package
pgherveou Jun 8, 2026
f0d7518
Use core-owned session storage key
pgherveou Jun 8, 2026
e4cf13b
Test core-owned disconnect UI path
pgherveou Jun 8, 2026
0f7abb7
Document Rust TrUAPI bridge
pgherveou Jun 8, 2026
820fced
fix(ui): emit cached preimage immediately
pgherveou Jun 8, 2026
385fd30
test(ui): cover theme callback parity
pgherveou Jun 8, 2026
dd683eb
test(ui): guard Nova host removal
pgherveou Jun 8, 2026
4e518a4
fix(host): copy truapi wasm bundle
pgherveou Jun 8, 2026
8ac0966
fix(host): wire full runtime config
pgherveou Jun 8, 2026
af3c47e
test(ui): guard storage adapter removal
pgherveou Jun 8, 2026
b24e467
docs: list removed storage adapter
pgherveou Jun 8, 2026
5a07915
refactor(config): drop nested bridge limit
pgherveou Jun 8, 2026
dd9bf57
fix(ui): satisfy truapi adapter lint
pgherveou Jun 8, 2026
2519ea6
test(ui): cover truapi adapter callbacks
pgherveou Jun 8, 2026
26803ae
chore(dotli): merge upstream main
pgherveou Jun 9, 2026
a045433
fix(ui): remove stale nova dependency list
pgherveou Jun 9, 2026
b5f6e37
fix(ui): use SSO V2 runtime config
pgherveou Jun 9, 2026
2edfebd
fix(ui): restore local signin
pgherveou Jun 9, 2026
d593ca0
fix(ui): close signin modal after pairing
pgherveou Jun 9, 2026
8dc9a7a
fix(debug): restore SSO pairing events
pgherveou Jun 9, 2026
a2652b8
fix(debug): trace SSO statement store
pgherveou Jun 9, 2026
2c1d009
fix(debug): expand system event labels
pgherveou Jun 9, 2026
c0ba1e3
fix(resolver): support People RPC chains
pgherveou Jun 9, 2026
27db1b1
fix(auth): treat rejected login as cancel
pgherveou Jun 9, 2026
50ded64
fix(dotli): stabilize SSO host flow
pgherveou Jun 9, 2026
e73a866
fix(truapi): allow local product id override
pgherveou Jun 9, 2026
0094e7e
refactor(truapi): share host callback hex utilities
pgherveou Jun 9, 2026
48943c9
fix(truapi): harden storage byte encoding
pgherveou Jun 9, 2026
f570bf3
chore(truapi): remove stale preimage note
pgherveou Jun 9, 2026
088f111
refactor(truapi): use scure base64 codec
pgherveou Jun 9, 2026
e38911d
refactor(truapi): drop host pairing-poll shim
pgherveou Jun 10, 2026
ad868ee
feat(truapi): adopt core session-UI events
pgherveou Jun 10, 2026
d07eed7
chore(ui): drop dead wallet queue and hex aliases
pgherveou Jun 10, 2026
f1dd9d8
docs: note truapi file-dependency packaging TODO
pgherveou Jun 10, 2026
6c4b8d4
fix(truapi): keep host login global
pgherveou Jun 10, 2026
4e607a7
fix(truapi): keep login modal global
pgherveou Jun 10, 2026
843c21f
fix(truapi): guard login rejection shape
pgherveou Jun 10, 2026
95b7e5a
fix(truapi): disconnect auth core on logout
pgherveou Jun 10, 2026
990b8d7
fix(truapi): treat rejected login as cancellation
pgherveou Jun 10, 2026
fad6df9
fix(truapi): rotate SSO identity on logout
pgherveou Jun 10, 2026
4e9b02f
fix(truapi): suppress rejected login error modal
pgherveou Jun 10, 2026
c8e1767
fix(truapi): keep first login click visible
pgherveou Jun 10, 2026
efa7bb2
fix(truapi): harden bridge debug paths
pgherveou Jun 10, 2026
a729e03
fix(truapi): harden login bridge entrypoints
pgherveou Jun 10, 2026
c747303
fix(truapi-debug): align wire event docs
pgherveou Jun 10, 2026
4bea19d
fix(host): resolve truapi wasm bundle from node_modules
pgherveou Jun 10, 2026
5790145
auth state change
pgherveou Jun 11, 2026
21054b2
test(host): add playground diagnosis e2e runner
pgherveou Jun 11, 2026
82f8576
test(host): add e2e QR smoke mode
pgherveou Jun 11, 2026
50fb22d
test(host): default signer bot target
pgherveou Jun 11, 2026
bd85d75
test(host): clarify signer bot login failures
pgherveou Jun 11, 2026
c859f63
test(host): capture e2e flow screenshots
pgherveou Jun 11, 2026
7f92d4e
test(host): clean up e2e diagnosis artifacts
pgherveou Jun 11, 2026
b176736
test(host): pregrant camera for diagnosis e2e
pgherveou Jun 11, 2026
832fe42
test(host): persist diagnosis e2e artifacts
pgherveou Jun 11, 2026
1cfdefb
fix(ui): align truapi host integration
pgherveou Jun 12, 2026
5aeebfd
fix(ui): drop user id permission
pgherveou Jun 12, 2026
a318fa1
refactor(ui): align host core API
pgherveou Jun 13, 2026
f7e77f0
refactor(ui): finish host core callbacks
pgherveou Jun 25, 2026
8e2c743
fix(ui): route auth through core storage
pgherveou Jun 25, 2026
f785040
test(e2e): pair from bare host origin
pgherveou Jun 25, 2026
7908869
merge rust core host integration
pgherveou Jun 25, 2026
ad2e5b2
test: stabilize playground e2e harness
pgherveou Jun 25, 2026
47f9b9f
fix(ui): route host auth through rust core
pgherveou Jun 28, 2026
0b65251
refactor(host): require complete callbacks
pgherveou Jun 29, 2026
6bfc60a
fix(ui): normalize core chain rpc requests
pgherveou Jun 29, 2026
1c0c78a
fixes
pgherveou Jun 29, 2026
e971a34
fix(ui): simplify core storage callbacks
pgherveou Jun 29, 2026
8e1b6b9
feat(ui): bridge legacy host-api products
pgherveou Jun 30, 2026
b18bb3c
feat(ui): batch permission status reads
pgherveou Jun 30, 2026
9235eb9
chore(ui): satisfy lint rules
pgherveou Jun 30, 2026
41b51b5
fix(host): stabilize truapi diagnosis flows
pgherveou Jul 1, 2026
e50a82a
fix(ui): align truapi pairing runtime
pgherveou Jul 3, 2026
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
106 changes: 106 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# dotli host layer migration to TrUAPI

This document records the current dotli host cutover state. The old
`@novasamatech/*` host-container path is no longer part of the runtime design:
dotli launches products through the Rust-backed TrUAPI host bridge and keeps
only its own `.dot` resolution/smoldot protocol outside that boundary.

## Current integration

dotli still has two protocol layers:

1. Host-product API frames, handled by TrUAPI.
2. dotli's internal host-smoldot protocol in `packages/protocol/`, which owns
`.dot` resolution and is not replaced by TrUAPI.

The active launch path is `packages/ui/src/bridge.ts`:

- imports `@parity/truapi-host-wasm/web` and
`@parity/truapi-host-wasm/worker-runtime?worker`;
- starts a Web Worker that owns the `truapi-server` WASM core;
- adapts typed dotli callbacks with `createWasmRawCallbacks(...)`;
- calls `createWebWorkerProvider(new HostWorker(), rawCallbacks, { runtimeConfig })`;
- supplies callbacks from `packages/ui/src/host-callbacks/handlers.ts`;
- calls `createIframeHost(...)` with the product URL, sandbox policy, allowed
origin, and the worker-backed provider.

Product frames enter the Rust core through the iframe `MessageChannel`.
Account, signing, statement-store, SSO pairing, restore, and logout are
core-owned and do not cross the JS host callback boundary as Nova-specific
routes.

## dotli callback boundary

dotli still supplies platform primitives that are host policy or browser UI:

| Area | Files |
| ------------------------- | -------------------------------------------------------------------------------------- |
| navigation | `packages/ui/src/host-callbacks/OpenUrl.ts` |
| notifications | `packages/ui/src/host-callbacks/PushNotification.ts` |
| device/remote permissions | `packages/ui/src/host-callbacks/PromptPermission.ts`, `packages/ui/src/permissions.ts` |
| feature support | `packages/ui/src/host-callbacks/FeatureSupported.ts` |
| product storage | `packages/ui/src/host-callbacks/LocalStorage.ts` |
| session persistence | `packages/ui/src/host-callbacks/SessionStore.ts` |
| pairing presentation | `packages/ui/src/host-callbacks/Pairing.ts` |
| user confirmations | `packages/ui/src/host-callbacks/UserConfirmation.ts` |
| preimage lookup UI | `packages/ui/src/host-callbacks/Preimage.ts` |
| theme subscription | `packages/ui/src/host-callbacks/Theme.ts` |
| chain backend connection | `packages/ui/src/host-callbacks/Chain.ts` |

These callbacks must remain generic host primitives. They should not re-add
Nova package imports, wallet-specific JS channels, or statement-store request
routing that belongs inside the Rust core.

## Dependencies

`packages/ui/package.json` depends on the local TrUAPI packages:

```jsonc
"@parity/truapi": "file:../../../../js/packages/truapi",
"@parity/truapi-host-wasm": "file:../../../../js/packages/truapi-host-wasm"
```

> **TODO(packaging):** the `file:../../../../` links resolve only when dotli
> lives at `hosts/dotli/` inside the TrUAPI monorepo. A standalone dotli
> checkout (including dotli's own CI, which runs `bun install
> --frozen-lockfile` without the parent repo) cannot install these packages.
> Before this branch lands on dotli `main`, decide between publishing the
> `@parity/truapi*` packages to a registry, vendoring tarballs, or retiring
> dotli's standalone CI. Carry this note into the dotli PR description.

The runtime manifests and source must not depend on or import the removed
`@novasamatech/*` runtime packages. The canonical forbidden-package list lives
in `packages/ui/tests/nova-removal.test.ts`; keep that guard broad rather than
duplicating a package list in this document.

`packages/ui/tests/nova-removal.test.ts` guards this invariant across dotli
manifests, `bun.lock`, `THIRD_PARTY_NOTICES.md`, `apps/*/src`, and
`packages/*/src`.

## Nested dApps

The old `setupNestedBridgeDetector` path created extra JS bridges for nested
iframe sources. TrUAPI v1 does not create separate nested Rust runtimes,
sessions, product identities, or storage namespaces. If nested traffic is
forwarded later, it must use the shared top-level Rust core/provider context.

The future usefulness of independent nested-product semantics is tracked in the
parent TrUAPI design note `docs/design/host-contract-and-core-impl/I -
nested-dapps.md`.

## Non-TrUAPI dotli layers

These areas remain dotli-owned and are intentionally outside the host-product
replacement:

- `apps/host/src/main.ts`: landing shell, `.dot` resolution, iframe mounting.
- `apps/sandbox/src/main.ts`: content renderer.
- `packages/protocol/`: smoldot protocol client/broker/session plumbing.
- `packages/resolver/`: `.dot` name resolution.
- `packages/content/` and `packages/storage/`: archive fetch and cache.
- `packages/config/`, `packages/metrics/`, and `packages/shared/`: support
libraries.

When auditing the migration, treat Nova runtime imports/dependencies as a
regression, but do not confuse dotli's internal `packages/protocol/` with the
removed host-product protocol.
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Each product gets its own `<label>.app.paseo.li` origin, so versions of the same

1. **Resolves** `.dot` names via an in-browser [smoldot](https://github.com/paritytech/smoldot) light client connected to Asset Hub Paseo, querying dotNS contracts.
2. **Fetches** content from the [Bulletin Chain](https://github.com/paritytech/polkadot-bulletin-chain) via smoldot `bitswap_v1_get` JSON-RPC or an IPFS gateway.
3. **Renders** the content in a sandboxed iframe with a full host-container bridge, so loaded SPAs can request accounts, sign transactions, connect to chains, and use scoped storage.
3. **Renders** the content in a sandboxed iframe with the Rust-backed TrUAPI bridge, so loaded SPAs can request accounts, sign transactions, connect to chains, and use scoped storage.

```
host-playground.paseo.li
Expand Down Expand Up @@ -116,26 +116,24 @@ On repeat visits, content renders instantly from the cache while it is resolved

If a background re-resolution finds the on-chain CID has changed, dotli shows a **New version available** notification with a **Reload** action rather than swapping content silently.

## Host-container bridge
## TrUAPI bridge

Loaded SPAs communicate with dotli through a postMessage-based protocol. The bridge exposes:

| Handler | What it does |
| ------------------------------ | ---------------------------------------------------------------------- |
| `accountGet` | Derives a per-app public key via HDKD soft derivation |
| `getLegacyAccounts` | Returns non-derived (imported) accounts — always empty on the web host |
| `signPayload` / `signRaw` | Shows signing modals, delegates to host-papp session |
| `signPayload` / `signRaw` | Shows signing modals and routes signing through the active session |
| `chainConnection` | Returns a smoldot-backed JsonRpcProvider for supported chains |
| `localStorageRead/Write/Clear` | Scoped `localStorage` per `.dot` domain |
| `navigateTo` | Opens URLs in new tabs |
| `featureSupported` | Reports whether a feature is supported (e.g. a chain's genesis hash) |
| `connectionStatus` | Streams auth state changes to the SPA |

### Nested dApp support
### App iframe model

dApps can embed other dApps via iframes (e.g. a marketplace app embedding a payments app). The host automatically detects nested dApps and creates separate bridges for each one, regardless of nesting depth.

When the host receives a protocol message from an unknown iframe window, it dynamically creates a new container bridge targeting that window. The dApp SDK always sends to `window.top`, so all nested dApps communicate directly with the host — no relay needed.
The host creates one TrUAPI bridge for the rendered product iframe. dApp-in-dApp iframes are opaque to the host and must use the top-level product's shared Rust core/provider context rather than separate host-created bridges.

The app context uses `document.write()` to eliminate extra iframe nesting: when loaded inside a host iframe, the app replaces its own document with the dApp content so the dApp occupies the iframe directly.

Expand Down Expand Up @@ -174,7 +172,7 @@ The published tag on the [Releases page](https://github.com/paritytech/dotli/rel

## Debug panel

dotli ships a TrUAPI debug panel that aggregates host-side activity (boot/resolve/render/bridge events, TrUAPI host↔product messages, host-papp SSO/session events) into one time-aligned inspector. The panel chunk is dynamically imported, so users who never see it pay no download cost.
dot.li ships a TrUAPI debug panel that aggregates host-side activity (boot/resolve/render/bridge events, TrUAPI host↔product messages, SSO/session events) into one time-aligned inspector. The panel chunk is dynamically imported, so users who never see it pay no download cost.

In builds compiled with `VITE_APP_DEBUG=true` (local `bun run preview:debug`, and the staging dev deploys at `paseoli.dev` / `dotli.dev`) the panel auto-mounts collapsed. In staging/production it's off until you click **Open in debug mode** in the host Settings menu (or append `?debug=true` to any URL). The choice is sessionStorage-scoped — closing the tab clears it. Use `?debug=off` to silence it explicitly within the same session.

Expand Down
Loading
Loading