@polkadot-apps/host
v0.5.1
Published
Host container detection and storage access for Polkadot Desktop and Mobile environments
Readme
@polkadot-apps/host
Host container detection and storage access for Polkadot Desktop and Mobile environments.
Install
pnpm add @polkadot-apps/host
# or
npm install @polkadot-apps/hostPeer Dependencies
@novasamatech/product-sdk is an optional peer dependency. When available, it is used as the primary container detection mechanism. The package works without it by falling back to manual environment checks.
pnpm add @novasamatech/product-sdkQuick Start
import { isInsideContainer, getHostLocalStorage, getHostProvider } from "@polkadot-apps/host";
if (await isInsideContainer()) {
const storage = await getHostLocalStorage();
await storage?.writeString("last-visit", new Date().toISOString());
}
// Get a host-routed chain provider (returns null outside a container)
const provider = await getHostProvider("0xabc...", wsProvider) ?? wsProvider;Container Detection
isInsideContainer determines whether the current page is running inside the Polkadot Desktop or Mobile shell.
import { isInsideContainer } from "@polkadot-apps/host";
const hosted = await isInsideContainer();
// true when running inside Polkadot Desktop/Mobile, false otherwiseDetection Signals
The function checks the following signals, in order:
- product-sdk sandboxProvider -- If
@novasamatech/product-sdkis installed, its sandbox provider is used as the authoritative check. __HOST_WEBVIEW_MARK__-- A global flag injected by the mobile WebView shell.__HOST_API_PORT__-- A global variable set by the desktop host process.- iframe detection -- Checks whether the page is embedded in an iframe, which may indicate a container context.
The function returns true as soon as any signal matches.
Host localStorage
When running inside a container, getHostLocalStorage returns a HostLocalStorage object that bridges to the host application's persistent storage. Outside a container it returns null.
import { getHostLocalStorage } from "@polkadot-apps/host";
const storage = await getHostLocalStorage();
if (storage) {
// String values
await storage.writeString("theme", "dark");
const theme = await storage.readString("theme"); // "dark"
// Structured data (serialized as JSON)
await storage.writeJSON("preferences", { locale: "en", currency: "DOT" });
const prefs = await storage.readJSON("preferences");
// Clear all host storage
await storage.clear();
} else {
// Not inside a container -- fall back to window.localStorage
}Host Provider
When running inside a Polkadot container, getHostProvider wraps chain connections through the host's shared connection pool, enabling efficient routing and resource sharing.
import { getHostProvider } from "@polkadot-apps/host";
import { getWsProvider } from "polkadot-api/ws-provider/web";
const ws = getWsProvider("wss://rpc.example.com");
const provider = await getHostProvider("0xabc...", ws);
if (provider) {
// Inside container — connections route through the host
const client = createClient(provider);
} else {
// Outside container — use WebSocket directly
const client = createClient(ws);
}Statement Store
When running inside a container, getStatementStore returns a statement store client that communicates through the host's native binary protocol — bypassing JSON-RPC entirely.
import { getStatementStore } from "@polkadot-apps/host";
const store = await getStatementStore();
if (store) {
// Inside container — subscribe, createProof, submit go through host API
store.subscribe(topics, (statements) => { /* ... */ });
} else {
// Outside container — fall back to direct WebSocket
}This is used internally by @polkadot-apps/statement-store for its host-first transport strategy.
Chain Config
Shared bulletin chain endpoint configuration, used by both @polkadot-apps/chain-client and @polkadot-apps/statement-store:
import { BULLETIN_RPCS, DEFAULT_BULLETIN_ENDPOINT } from "@polkadot-apps/host";
// BULLETIN_RPCS.paseo → ["wss://paseo-bulletin-rpc.polkadot.io"]
// DEFAULT_BULLETIN_ENDPOINT → "wss://paseo-bulletin-rpc.polkadot.io"API
| Function | Signature | Description |
|---|---|---|
| isInsideContainer | () => Promise<boolean> | Detect if running inside the Polkadot Desktop/Mobile container. Uses product-sdk as the primary signal, with manual fallbacks. |
| getHostLocalStorage | () => Promise<HostLocalStorage \| null> | Get the host localStorage bridge when inside a container. Returns null outside a container. |
| getHostProvider | (genesisHash, fallback?) => Promise<JsonRpcProvider \| null> | Get a host-routed PAPI provider. Returns null when product-sdk is unavailable. |
| getStatementStore | () => Promise<HostStatementStore \| null> | Get the host statement store (subscribe/createProof/submit). Returns null when product-sdk is unavailable. |
Types
interface HostLocalStorage {
/** Read a string value by key. */
readString(key: string): Promise<string | null>;
/** Write a string value. */
writeString(key: string, value: string): Promise<void>;
/** Read and deserialize a JSON value. */
readJSON<T = unknown>(key: string): Promise<T | null>;
/** Serialize and write a JSON value. */
writeJSON<T = unknown>(key: string, value: T): Promise<void>;
/** Clear all stored values. */
clear(): Promise<void>;
}License
Apache-2.0
