# host-extensions
Extension framework for host-sdk. Extensions add new capabilities to a
Polkadot host application without touching core — each extension is an
independent JS/native bridge registered under `window.host.ext.<namespace>`.
## Purpose
The core `window.host` bridge (host-api) handles signing, storage, navigation,
and chain interaction. Extensions cover everything else: structured data, media,
notifications, payments, identity, etc.
Extensions are **experimental by design**. A new API lives under
`window.host.ext.*` while it is being qualified. Once an API is stable and
widely adopted it graduates to core (`window.host.*`) with a compatibility
shim keeping the old path alive.
## Extension lifecycle
```
experimental qualified core
window.host.ext.data → (shim period) → window.host.data
```
For the full guide — including how to implement an extension, the JS contract,
the manifest format, and the graduation path — see
[docs/extensions.md](../../docs/extensions.md).
## Quick start
```rust
use host_extensions::{HostExtension, ExtensionRegistry};
struct MyExtension;
impl HostExtension for MyExtension {
fn namespace(&self) -> &str { "my" }
fn channel(&self) -> &str { "hostMyBridge" }
fn inject_script(&self) -> &str { include_str!("my_inject.js") }
fn handle_message(&self, method: &str, params: &str) -> Option<String> {
match method {
"ping" => Some(r#"{"pong":true}"#.into()),
_ => None,
}
}
}
let mut registry = ExtensionRegistry::new();
registry.register(Box::new(MyExtension));
// Inject into WebView after HOST_API_BRIDGE_SCRIPT
let script = registry.combined_inject_script();
// Register WKScriptMessageHandler for each channel
for channel in registry.channels() {
webview.add_message_handler(channel);
}
// Dispatch incoming messages
let result = registry.dispatch("hostMyBridge", "ping", "{}");
```