Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
ddf0786
feat(core): implement ring-vrf signing
pgherveou Jul 17, 2026
d59fdb1
Merge branch 'main' into feat/signing-host-ring-vrf
pgherveou Jul 20, 2026
5911457
Merge branch 'main' into feat/signing-host-ring-vrf
pgherveou Jul 21, 2026
01513f9
update
pgherveou Jul 23, 2026
bc2a5fe
analyse and fix diff with ~/github/polkadot-app-android-v2/
pgherveou Jul 23, 2026
1aed8f4
fixup
pgherveou Jul 23, 2026
5489b13
fixes
pgherveou Jul 23, 2026
132f667
fix(core): align host compatibility
pgherveou Jul 23, 2026
7c96e27
Merge main into feat/signing-host-ring-vrf
pgherveou Jul 23, 2026
5dd8ef1
ci: refresh generated fixture and licenses
pgherveou Jul 23, 2026
6868f0b
fix(sso-responder): bound the replay-dedup set to cap memory
TarikGul Jul 24, 2026
f7999e3
chore(codegen): refresh stale host-callbacks golden
TarikGul Jul 24, 2026
eaaa22b
fix(signing-host): name the beneficiary product in the allocation review
TarikGul Jul 24, 2026
d8168ad
chore(codegen): refresh host-callbacks golden for ResourceAllocationR…
TarikGul Jul 24, 2026
0bed52d
fix(signing-host): use a dedicated review for statement-store proof s…
TarikGul Jul 24, 2026
16009a1
Clippy / fmt
TarikGul Jul 24, 2026
a4e8e40
Merge branch 'feat/signing-host-ring-vrf' of github.com:paritytech/tr…
TarikGul Jul 24, 2026
103431c
fix(server): align runtime SCALE codecs
pgherveou Jul 23, 2026
0e7e96e
update
pgherveou Jul 24, 2026
fa9f1fb
refactor(api): adopt Send async traits
pgherveou Jul 24, 2026
bd69991
feat(ios): integrate the shared Rust runtime core
Jul 24, 2026
8aebcf3
fix(playground): run account proof diagnosis
Jul 24, 2026
2da2e8b
feat(ios): dispatch native frames across Tokio workers
Jul 24, 2026
f29b3c2
refactor(native): share the Tokio bridge runtime
Jul 24, 2026
f57a7da
refactor(native): clarify shared executor naming
Jul 24, 2026
aa65521
make host callbacks async
ERussel Jul 30, 2026
86e0bc7
merge conflict
ERussel Jul 30, 2026
b11449d
fix conflicts
ERussel Jul 30, 2026
3b56a85
Merge branch 'main' into rus-ios-integration
ERussel Jul 30, 2026
0235f62
feat: integrate chat modality with shared core
Aug 1, 2026
21e143b
build: pin the codegen nightly toolchain
Aug 1, 2026
3e43747
make callbacks interface type instead of scale encoded
ERussel Aug 2, 2026
bc81751
feat: finalize shared-core chat modality integration
Aug 3, 2026
5d319fc
refactor: simplify shared-core chat integration
Aug 3, 2026
f9dfd21
chore: update chat host integrations
Aug 3, 2026
36a2ca8
Merge branch 'main' into rus-ios-integration
ERussel Aug 3, 2026
e7c76e3
async host callbacks and publish+release script
ERussel Aug 3, 2026
b0139fa
fix clippy
ERussel Aug 4, 2026
ed36752
remove unused method
ERussel Aug 4, 2026
e6dc40c
move ios truhost to separate repo
ERussel Aug 4, 2026
ea9453a
fix min version during build
ERussel Aug 4, 2026
d66ad2e
fix conflicts
ERussel Aug 5, 2026
dd7cae5
move distribution back to truapi
ERussel Aug 5, 2026
69dba9f
moved container to js
ERussel Aug 5, 2026
3ac65b0
rename and fix bridge test after moving to async/await
ERussel Aug 5, 2026
dd3d16d
refactor: pass canonical review types through uniffi via remote decla…
pgherveou Aug 5, 2026
3ba49e8
refactor: inline review FFI declarations into native.rs
pgherveou Aug 5, 2026
f2d8c0e
rebuild bindings
ERussel Aug 5, 2026
d07df42
update package.swift after publish
ERussel Aug 5, 2026
5fd7b99
refactor: derive uniffi on the canonical review types
pgherveou Aug 5, 2026
680d3e7
Merge remote-tracking branch 'origin/rus-ios-integration' into pg/uni…
pgherveou Aug 5, 2026
9691ce4
build(ios): ship the three uniffi namespaces in the TrUAPIHost package
pgherveou Aug 5, 2026
a0700b2
Merge remote-tracking branch 'origin/main' into pg/uniffi-remote-revi…
pgherveou Aug 5, 2026
e4f2786
refactor: attach the FFI conversion to [u8; 32] via a plain alias
pgherveou Aug 5, 2026
b1ef97a
Merge remote-tracking branch 'origin/main' into pg/uniffi-remote-revi…
pgherveou Aug 5, 2026
9eede36
feat: vendor the Android host app as the hosts/android submodule
pgherveou Aug 5, 2026
4c72bae
refactor: expose the canonical NavigateDecision over FFI
pgherveou Aug 5, 2026
3e3754f
refactor: derive uniffi on the remaining pure-mirror callback types
pgherveou Aug 5, 2026
5294a22
refactor: canonical theme and permission-status enums over FFI
pgherveou Aug 6, 2026
2d956e9
refactor: canonical auth-state and permission-authorization types ove…
pgherveou Aug 6, 2026
d0e7162
refactor: host-thrown errors wrap canonical payload enums
pgherveou Aug 6, 2026
68d037f
refactor!: rename DerivationIndex variants to Index and Raw
pgherveou Aug 6, 2026
38a2f53
docs: spec custom rendering as a host-initiated subscription
pgherveou Aug 6, 2026
441aa4d
fix
Aug 6, 2026
235a8b7
refactor: unify shared-core chat rendering
Aug 6, 2026
456b10c
revert: drop unrelated nightly toolchain pinning
pgherveou Aug 6, 2026
3ab8523
docs: drop ancillary chat design notes
pgherveou Aug 6, 2026
2f4fa93
Merge remote-tracking branch 'origin/main' into feat/chat-modality-sh…
pgherveou Aug 6, 2026
7f1e4e1
Merge origin/main into feat/chat-modality-shared-core
pgherveou Aug 6, 2026
3cd19ab
revert: drop unrelated diagnosis workflow changes
pgherveou Aug 6, 2026
69b9328
fix(ios): expose product execution boundary
pgherveou Aug 6, 2026
421332e
test(codegen): isolate rustfmt golden formatting
pgherveou Aug 6, 2026
4a85ac2
chore(codegen): refresh host callbacks golden
pgherveou Aug 6, 2026
2ad698a
fix(chat): make local iOS integration reproducible
Aug 6, 2026
0da49a4
refactor: rename app execution kind to spa
Aug 6, 2026
8680e64
fix(bindings): upgrade UniFFI to 0.32
pgherveou Aug 6, 2026
efc274f
fix(codegen): update derivation index examples
pgherveou Aug 7, 2026
cb9a268
docs(bindings): explain native error wrappers
pgherveou Aug 7, 2026
bf631ed
rm doc
Aug 7, 2026
170dc47
rm
Aug 7, 2026
967e274
fixes
Aug 7, 2026
b2987a6
revert: do not vendor Android host app
Aug 7, 2026
458acc7
fix(android): refresh Kotlin host build
pgherveou Aug 7, 2026
e0c92d1
build(ios): publish host XCFramework 0.4.0
Aug 7, 2026
2ae681d
ci(ios): publish host binaries from releases
Aug 7, 2026
d4bda00
Merge branch 'pg/uniffi-remote-review-types' into feat/chat-modality-…
Aug 7, 2026
8ac2dc8
Merge remote-tracking branch 'origin/main' into feat/chat-modality-sh…
Aug 7, 2026
048caac
simplify
pgherveou Aug 7, 2026
95ff743
style(server): format native chat tests
Aug 8, 2026
b66585d
build(ios): publish chat shared-core XCFramework
Aug 8, 2026
787729a
Merge remote-tracking branch 'origin/main' into feat/chat-modality-sh…
Aug 8, 2026
4ca9378
ci(rust): allow async-trait double must-use lint
Aug 8, 2026
dc83cd3
build(ios): refresh chat shared-core XCFramework
Aug 8, 2026
877274a
ci(rust): allow async-trait platform lint
Aug 8, 2026
330591a
ci(rust): allow async-trait server lint
Aug 8, 2026
57a48d0
refactor(server): review cleanups for the chat shared core
pgherveou Aug 8, 2026
940dfec
build(ios): regenerate chat callback bindings
Aug 8, 2026
a66f02a
build(ios): publish refreshed shared-core XCFramework
Aug 8, 2026
e63b76f
fix(explorer): label host-initiated subscriptions
Aug 8, 2026
09ef3fe
fix(ios): route chain events to shared services
Aug 8, 2026
306f5e3
build(ios): publish native event routing fix
Aug 8, 2026
f22dd90
refactor(native): expose canonical renderer types
Aug 8, 2026
596ef5e
rm agents.md
Aug 8, 2026
7ae38a7
refactor(renderer): remove unused generic component
Aug 8, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ lerna-debug.log*
# Build artifacts
node_modules
target
/artifacts/

# SwiftPM (root Package.swift for ios/truapi-host)
/.build/
Expand Down
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ scripts/battery.sh run the generated battery against both headless CLI h
rather than importing a concrete protocol version. Runtime crates may use
`truapi::versioned::*` for wire envelopes, but should unwrap them into latest
payloads immediately.
- Native bindings expose canonical Rust domain and protocol types directly.
Add feature-gated UniFFI derives to those types and custom conversions for
unsupported leaf values instead of defining parallel `Native*` mirrors.
Boundary-specific native types are reserved for lifecycle or callback
behavior that has no canonical value-type equivalent.
- `truapi-server` WASM artifacts live under
`js/packages/truapi-host/dist/wasm/web/` and are gitignored.
Build them locally with `make wasm` (rerun whenever
Expand Down
83 changes: 82 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Run `make help` for the list of targets.

.DEFAULT_GOAL := help
.PHONY: help setup build codegen test check clean playground wasm wasm-crypto-test uniffi uniffi-kotlin android-jni android-publish-local dotli-link dev dev-bootstrap dev-link-check e2e-dotli e2e-signing-cli e2e-pairing-cli headless install matrix explorer xcframework
.PHONY: help setup build codegen test check clean playground wasm wasm-crypto-test uniffi uniffi-kotlin ios-build ios-run ios-chat-run ios-chat-host-playground-run ios-chat-all android-jni android-publish-local dotli-link dev dev-bootstrap dev-link-check e2e-dotli e2e-signing-cli e2e-pairing-cli headless install matrix explorer xcframework

CARGO ?= cargo
TRUAPI_PKG := js/packages/truapi
Expand Down Expand Up @@ -41,6 +41,7 @@ setup: ## First-time setup: submodules, JS dependencies, generated artifacts.
# that only exist after codegen.sh, which also builds the packages.
npm ci --ignore-scripts
./scripts/codegen.sh
$(MAKE) uniffi
cd $(PLAYGROUND) && yarn install --frozen-lockfile
cd $(DOTLI) && bun install --frozen-lockfile
$(MAKE) dotli-link
Expand Down Expand Up @@ -96,6 +97,86 @@ uniffi: ## Generate Swift bindings from the truapi-server cdylib into target/uni
--language swift \
--out-dir $(UNIFFI_SWIFT_TMP)

IOS_HOST ?= ../polkadot-app-ios-v2
IOS_DERIVED_DATA ?= $(IOS_HOST)/build/DerivedData
IOS_CONFIGURATION ?= Debug
IOS_SWIFT_FLAGS ?= -DNIGHTLY -DW3S -DIOS_PASEO_E2E
IOS_SIMULATOR_DEVICE ?=
IOS_XCODE_DESTINATION ?= generic/platform=iOS Simulator
IOS_BUNDLE ?= io.pcf.polkadotapp.develop
IOS_GOOGLE_SERVICE_PLIST ?= $(IOS_HOST)/polkadot-app/GoogleService/GoogleService-Info-Release.plist
IOS_PRODUCT_HOST ?= truapi-playground.dot
IOS_PRODUCT_URL ?= http://localhost:3100
IOS_CHAT_PRODUCT_DIR ?= playground
IOS_CHAT_PRODUCT_HOST ?= truapi-playground.dot
IOS_CHAT_PRODUCT_NAME ?= TrUAPI Playground
IOS_CHAT_PRODUCT_URL ?= http://127.0.0.1:3100
IOS_HOST_PLAYGROUND_DIR ?= ../host-playground
IOS_HOST_PLAYGROUND_HOST ?= host-playground.dot
IOS_HOST_PLAYGROUND_NAME ?= Host Playground
IOS_HOST_PLAYGROUND_URL ?= http://127.0.0.1:3101
IOS_APP := $(abspath $(IOS_DERIVED_DATA)/Build/Products/$(IOS_CONFIGURATION)-iphonesimulator/polkadot-app.app)

ios-build: ## Rebuild the local Rust package and the TestFlight-configured iOS simulator app.
@test -d "$(IOS_HOST)/.git" || { \
echo "Missing iOS checkout at $(IOS_HOST); set IOS_HOST to polkadot-app-ios-v2"; \
exit 1; \
}
./ios/truapi-host/scripts/rebuild.sh
cd $(IOS_HOST) && \
TRUAPI_LOCAL_PATH="$(CURDIR)" \
TRUAPI_USE_LOCAL_BINARY=1 \
RUN_IN_CI=true xcodebuild \
-project polkadot-app.xcodeproj \
-scheme polkadot-app \
-configuration $(IOS_CONFIGURATION) \
-destination '$(IOS_XCODE_DESTINATION)' \
-derivedDataPath $(abspath $(IOS_DERIVED_DATA)) \
ARCHS=arm64 \
ONLY_ACTIVE_ARCH=YES \
BASE_SWIFT_FLAGS='$(IOS_SWIFT_FLAGS)' \
clean build
cp "$(IOS_GOOGLE_SERVICE_PLIST)" "$(IOS_APP)/GoogleService-Info.plist"
codesign --force --sign - --preserve-metadata=entitlements "$(IOS_APP)"

ios-run: ios-build ## Build and launch the local TrUAPI playground in an iPhone simulator.
TRUAPI_IOS_E2E_DEVICE="$(IOS_SIMULATOR_DEVICE)" \
TRUAPI_IOS_E2E_APP="$(IOS_APP)" \
TRUAPI_IOS_E2E_BUNDLE="$(IOS_BUNDLE)" \
TRUAPI_IOS_E2E_PRODUCT_HOST="$(IOS_PRODUCT_HOST)" \
TRUAPI_IOS_E2E_PRODUCT_URL="$(IOS_PRODUCT_URL)" \
node scripts/launch-ios-playground.mjs

ios-chat-run: ios-build ## Run the TrUAPI Playground Chat diagnosis in an iPhone simulator.
TRUAPI_IOS_E2E_DEVICE="$(IOS_SIMULATOR_DEVICE)" \
TRUAPI_IOS_E2E_APP="$(IOS_APP)" \
TRUAPI_IOS_E2E_BUNDLE="$(IOS_BUNDLE)" \
TRUAPI_IOS_E2E_CHAT_PRODUCT_DIR="$(IOS_CHAT_PRODUCT_DIR)" \
TRUAPI_IOS_E2E_CHAT_PRODUCT_HOST="$(IOS_CHAT_PRODUCT_HOST)" \
TRUAPI_IOS_E2E_CHAT_PRODUCT_NAME="$(IOS_CHAT_PRODUCT_NAME)" \
TRUAPI_IOS_E2E_CHAT_PRODUCT_URL="$(IOS_CHAT_PRODUCT_URL)" \
node scripts/launch-ios-chat-playground.mjs

ios-chat-host-playground-run: ios-build ## Verify Host Playground Chat through the workspace-linked TrUAPI client.
TRUAPI_IOS_E2E_DEVICE="$(IOS_SIMULATOR_DEVICE)" \
TRUAPI_IOS_E2E_APP="$(IOS_APP)" \
TRUAPI_IOS_E2E_BUNDLE="$(IOS_BUNDLE)" \
TRUAPI_IOS_E2E_CHAT_PRODUCT_DIR="$(abspath $(IOS_HOST_PLAYGROUND_DIR))" \
TRUAPI_IOS_E2E_CHAT_PRODUCT_HOST="$(IOS_HOST_PLAYGROUND_HOST)" \
TRUAPI_IOS_E2E_CHAT_PRODUCT_NAME="$(IOS_HOST_PLAYGROUND_NAME)" \
TRUAPI_IOS_E2E_CHAT_PRODUCT_URL="$(IOS_HOST_PLAYGROUND_URL)" \
TRUAPI_IOS_E2E_CHAT_ROOM_ID="host-playground-room" \
TRUAPI_IOS_E2E_CHAT_MESSAGE="!flip" \
TRUAPI_IOS_E2E_CHAT_EXPECTED_REPLY="Flipping the coin!" \
TRUAPI_IOS_E2E_CHAT_DIAGNOSIS="0" \
TRUAPI_IOS_E2E_CHAT_EXPECTED_STARTUP_MESSAGE="" \
TRUAPI_IOS_E2E_CHAT_EXPECT_CUSTOM_RENDERER="1" \
TRUAPI_IOS_E2E_CHAT_SCREENSHOT="artifacts/host-playground-coin-flip-chat.png" \
TRUAPI_IOS_E2E_CHAT_TRUAPI_DIR="$(abspath js/packages/truapi)" \
node scripts/launch-ios-chat-playground.mjs

ios-chat-all: ios-chat-run ios-chat-host-playground-run ## Run both local iOS Chat playground integrations.

UNIFFI_KOTLIN_OUT := android/truapi-host/src/main/kotlin/generated

uniffi-kotlin: ## Regenerate Kotlin UniFFI bindings from the truapi-server cdylib.
Expand Down
13 changes: 7 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
// ios/truapi-host/scripts/rebuild.sh); the xcframework is gitignored and
// distributed as a GitHub release asset (ios/truapi-host/scripts/publish.sh).

import Foundation
import PackageDescription

// Flip to true to build against the locally generated
// ios/truapi-host/Binaries/truapi_server.xcframework (run rebuild.sh first);
// false consumes the published release asset below (updated by publish.sh).
let useLocalBinary = false
// Set TRUAPI_USE_LOCAL_BINARY=1 to build against the locally generated
// ios/truapi-host/Binaries/truapi_server.xcframework (run rebuild.sh first).
// The published release asset remains the default for remote consumers.
let useLocalBinary = ProcessInfo.processInfo.environment["TRUAPI_USE_LOCAL_BINARY"] == "1"

let publishedBinaryURL = "https://github.com/paritytech/truapi/releases/download/%40parity%2Fios-host%400.4.0/truapi_server.xcframework.zip"
let publishedBinaryChecksum = "a3029c071ef37e876ae51e45c177eab09cb976f9dbd729b93a2191d6ca8331be"
let publishedBinaryURL = "https://github.com/paritytech/truapi/releases/download/%40parity%2Fios-host%400.4.0-chat-modality-shared-core.4/truapi_server.xcframework.zip"
let publishedBinaryChecksum = "b4d7e633e8a86bdaf104a1bcafc883549fc893514451fe7caeb951107e5038f7"

let binaryTarget: Target = useLocalBinary
? .binaryTarget(
Expand Down
66 changes: 62 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ manifest at the repo root (`Package.swift`) so apps can consume it as a git-URL
dependency. Its `scripts/rebuild.sh` regenerates the committed bindings and
container bundle (`make xcframework` + `make uniffi`); see
[`ios/truapi-host/README.md`](ios/truapi-host/README.md).
Native bindings expose the canonical Rust domain and protocol value types;
native-only adapter types are limited to lifecycle and callback behavior.

### JS Host SDKs

Expand Down Expand Up @@ -127,10 +129,9 @@ controls, and examples.

`scripts/battery.sh` drives that CLI from source over every code-generated
example and writes both committed compatibility reports:
`explorer/diagnosis-reports/signing-host-cli.md` from a direct signing-host run,
and `pairing-host-cli.md` from a pairing host that the script pairs with a
signing host it starts itself under the same product id. Known unsupported
service families remain visible in the reports without making the command fail.
`explorer/diagnosis-reports/spa/signing-host-cli.md` from a direct signing-host
run, and `spa/pairing-host-cli.md` from a pairing host that the script pairs with a
signing host it starts itself.

```bash
scripts/battery.sh # both phases
Expand All @@ -149,6 +150,63 @@ yarn dev

Open `https://dot.li/localhost:3000` inside the Polkadot Desktop Host. See [`playground/README.md`](playground/README.md) for deployment.

To build the iOS host and open the playground in Simulator:

```bash
make ios-run
```

The target regenerates the UniFFI Swift bindings, builds the matching Rust
simulator library, and builds the sibling `polkadot-app-ios-v2` checkout with the Nightly feature
flags and release Firebase app used by the Nightly TestFlight build. Native
Chat and the Paseo chain catalog come from the same Nightly Remote Config as
TestFlight. The executable keeps the development bundle and app-group identity
so Simulator can reuse its already registered wallet; keychain data cannot be
transferred to the production bundle. The simulator also adds the
`IOS_PASEO_E2E` conveniences needed to start on the real `browse.dot` Browse tab
and activate the embedded signing host. Embedded product host sessions use the
same Paseo People and Bulletin chains selected by the Nightly app
configuration. The launcher starts the playground at `http://localhost:3100`
when needed and uses that local source only after Browse opens
`truapi-playground.dot`. It refuses to launch if the local URL belongs to a
different app. Override the product, URL, or simulator with `IOS_PRODUCT_HOST`,
`IOS_PRODUCT_URL`, or `TRUAPI_IOS_E2E_DEVICE`. The simulator launch reuses the
wallet and registered username already stored by the iOS app. Opening a product
activates the embedded `truapi-host` signing-host session from that wallet; it
does not provision or pair a signer-bot user.

To exercise the shared-core Chat path with the first-party TrUAPI Playground
worker, build and serve the local product, install its worker into the
simulator app's product storage, and open its native Chat application:

```bash
make ios-chat-run
```

The launcher verifies the Chat connection and runs a correlated Chat-only
diagnosis. The worker proves create-room idempotency, observes the new room on
the live list subscription, posts text and custom messages, receives
`!diagnose` through `chat_action_subscribe`, and serves live renderer trees.
The launcher also verifies that a renderer update reaches native code and that
the final Markdown report reaches CoreData. It writes the host-labelled report
to `playground/test-results/ios-chat/diagnosis-report.md`. The product builds
against the workspace-linked `@parity/truapi`. Override the product source,
identity, SPA URL, room, input, or report path with
`IOS_CHAT_PRODUCT_DIR`, `IOS_CHAT_PRODUCT_HOST`, `IOS_CHAT_PRODUCT_URL`,
`TRUAPI_IOS_E2E_CHAT_ROOM_ID`, `TRUAPI_IOS_E2E_CHAT_MESSAGE`, or
`TRUAPI_IOS_E2E_CHAT_REPORT`.

The same harness can run the legacy Product SDK worker from the sibling
`host-playground` checkout. This target builds the current TrUAPI client, links
it over Host Playground's transitive `@parity/truapi`, then builds and runs
that product:

```bash
make ios-chat-host-playground-run
```

Run both integrations with one iOS build using `make ios-chat-all`.

## Regenerate the TypeScript client

When the Rust trait surface changes:
Expand Down
1 change: 0 additions & 1 deletion android/truapi-host/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ val endpoint = core.startWsBridge()

// Call these from host/platform observers so native subscriptions see updates
// after their immediate current item.
core.notifySessionStoreChanged()
core.notifyThemeChanged(ThemeVariant.DARK)
core.notifyPreimageChanged(preimageKey, preimageBytesOrNull)
core.notifyChainResponse(chainConnectionId, jsonRpcResponse)
Expand Down
4 changes: 2 additions & 2 deletions android/truapi-host/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ android {
dependencies {
// UniFFI Kotlin bindings use JNA for FFI.
api("net.java.dev.jna:jna:5.14.0@aar")
// UniFFI 0.32 uses coroutines to bridge async Rust functions and callbacks.
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
// UniFFI async functions and callbacks use cancellable continuations and jobs.
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
}

// Coordinates for the local Maven publication (`publishToMavenLocal`).
Expand Down
17 changes: 17 additions & 0 deletions android/truapi-host/src/main/kotlin/io/parity/truapi/TrUAPIHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import uniffi.truapi_server.HostCallbacks
import uniffi.truapi_server.HostNavigateRejection
import uniffi.truapi_server.HostRejection
import uniffi.truapi_server.HostStorageException
import uniffi.truapi_platform.ProductExecutionKind as UniFfiProductExecutionKind
import uniffi.truapi_server.NativeRuntimeConfigException
import uniffi.truapi_server.NativeTrUApiCore
import uniffi.truapi_server.WsBridgeEndpoint
Expand All @@ -63,6 +64,18 @@ enum class PairingDeeplinkScheme {
}
}

/** Trusted kind of executable attached to a product connection. */
enum class ProductExecutionKind {
SPA,
CHAT;

internal fun toNative(): UniFfiProductExecutionKind =
when (this) {
SPA -> UniFfiProductExecutionKind.SPA
CHAT -> UniFfiProductExecutionKind.CHAT
}
}

/**
* Static product and pairing config supplied before the Rust core handles
* product calls. One core instance represents one product identity.
Expand All @@ -75,6 +88,7 @@ enum class PairingDeeplinkScheme {
*/
data class RuntimeConfig(
val productId: String,
val executionKind: ProductExecutionKind = ProductExecutionKind.SPA,
val hostName: String,
val hostIcon: String? = null,
val hostVersion: String? = null,
Expand All @@ -89,6 +103,7 @@ data class RuntimeConfig(
internal fun toNative(): UniFfiNativeRuntimeConfig =
UniFfiNativeRuntimeConfig(
productId = productId,
executionKind = executionKind.toNative(),
hostName = hostName,
hostIcon = hostIcon,
hostVersion = hostVersion,
Expand All @@ -105,6 +120,7 @@ data class RuntimeConfig(
if (this === other) return true
if (other !is RuntimeConfig) return false
return productId == other.productId &&
executionKind == other.executionKind &&
hostName == other.hostName &&
hostIcon == other.hostIcon &&
hostVersion == other.hostVersion &&
Expand All @@ -122,6 +138,7 @@ data class RuntimeConfig(

override fun hashCode(): Int {
var result = productId.hashCode()
result = 31 * result + executionKind.hashCode()
result = 31 * result + hostName.hashCode()
result = 31 * result + (hostIcon?.hashCode() ?: 0)
result = 31 * result + (hostVersion?.hashCode() ?: 0)
Expand Down
6 changes: 3 additions & 3 deletions explorer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Docs-only browser for the TrUAPI service surface. All trait and type data is sou

## Host compatibility matrix

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.
The **Compatibility** page (`/v/<version>/compatibility`) renders separate SPA and Chat host × method matrices 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.

### Updating the matrix

Because the matrix is regenerated from `diagnosis-reports/` on every `dev` / `build` / `lint`, you only ever commit reports, never `src/data/compatibility.ts`.

**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.
**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/spa/<host>.md` (or `diagnosis-reports/chat/<host>.md` for Chat reports) and opens (or updates) that host's PR.

**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.
**By hand.** Click **Copy report** instead (see [`../playground/README.md#diagnosis`](../playground/README.md#diagnosis)), save the markdown to a host-named file under [`diagnosis-reports/spa/`](diagnosis-reports/spa/) (e.g. `spa/web.md`, `spa/desktop.md`, `spa/android.md`, `spa/ios.md`), overwriting that host's previous report, and commit. Chat worker reports live under [`diagnosis-reports/chat/`](diagnosis-reports/chat/), such as `chat/ios.md`, and are rendered in the separate Chat section. 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.

### Data shape

Expand Down
11 changes: 11 additions & 0 deletions explorer/diagnosis-reports/chat/ios.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Truapi iOS Chat Diagnosis

**5 success · 0 failed**

| Method | Status | Details |
| --- | --- | --- |
| `Chat/create_room` | ✅ | created once, then returned Exists |
| `Chat/list_subscribe` | ✅ | observed the newly created room |
| `Chat/post_message` | ✅ | posted text and custom messages |
| `Chat/action_subscribe` | ✅ | received MessagePosted with the originating room |
| `Chat/custom_message_render` | ✅ | served initial and replacement trees on a host-initiated render stream |
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@
| `Chain/get_spec_properties` | ✅ | |
| `Chain/broadcast_transaction` | ✅ | |
| `Chain/stop_transaction` | ✅ | |
| `Chat/create_room` | ❌ | timed out after 10s |
| `Chat/register_bot` | ❌ | registerBot failed: { "error": { "tag": "Unknown", "value": { "reason": "Not implemented" } } } |
| `Chat/list_subscribe` | ❌ | timed out after 10s |
| `Chat/post_message` | ❌ | postMessage failed: { "error": { "tag": "Unknown", "value": { "reason": "Error: Unknown method: chatSendTextMessage" } } } |
| `Chat/action_subscribe` | ❌ | timed out after 10s |
| `Chat/custom_message_render_subscribe` | ❌ | timed out after 10s |
| `Entropy/derive` | ✅ | |
| `Local Storage/read` | ✅ | |
| `Local Storage/write` | ✅ | |
Expand Down
Loading