@kehto/shell
v0.14.2
Published
Shell runtime — relay bridge, ACL enforcement, signer proxy, storage proxy for hosting napplet iframe applications
Maintainers
Readme
@kehto/shell
Browser adapter over @kehto/runtime — ShellBridge, domain proxies, keys-forwarder.
Alpha status: Kehto is an early runtime implementation for a draft NIP-5D protocol. NAP contracts,
supports()behavior, and shell capabilities are not final; treat this package as current implementation guidance.
Install
pnpm add @kehto/shellOverview
@kehto/shell is the browser-specific integration layer for kehto. It wraps @kehto/runtime with the window/postMessage transport, localStorage persistence hooks, an audio manager, and the five canonical per-domain proxies defined by NIP-5D.
The primary entry point is createShellBridge() — it owns the postMessage listener, the NAP-SHELL shell.ready / shell.init handshake, manifest verification, and every dispatch back into the runtime engine.
Current draft behaviors this package enforces:
- The shell does not inject a host-provided nostr object into napplets — NIP-5D explicitly forbids napplet-visible signing. Napplets call
relay.publish/relay.publishEncryptedand the shell mediates the signing flow internally (NIP-44 default, NIP-04 opt-in for encrypted envelopes). shell.supports(capability)uses theperm:<permission>namespace for sandbox permissions, not the v1.1 bare capability list.- Five optional per-domain proxies —
createIdentityProxy,createThemeProxy,createKeysProxy,createMediaProxy,createNotifyProxy— can be composed between napplet and runtime to intercept or augment traffic per NAP. They are NOT wired by default (Kehto's runtime already owns dispatch for the currently supported domains); they exist as host-app composition seams. - The keys-forwarder pumps host keydown events into
keys.forwardenvelopes for napplets that hold thekeys:forwardcapability.
Quick Start
import { createShellBridge } from '@kehto/shell';
import { createNotificationService } from '@kehto/services';
const bridge = createShellBridge({
adapter: myShellAdapter,
hooks: myHooks,
target: window,
});
// Register a reference service against the underlying runtime.
bridge.runtime.registerService(
'notifications',
createNotificationService({ onChange: updateBadge }),
);Public API
Bridge factory
createShellBridge— primary entry point; returns aShellBridge(exposedruntime,shell.ready, lifecycle hooks)ShellBridge— interface type for the returned bridge
Hooks adapter
adaptHooks— convert aShellAdapter+BrowserDepsinto the canonicalRuntimeAdapterhook bag consumed by@kehto/runtime
Diagnostics
ShellAdapter.onUnroutedMessage?(info)— optional observe-only hook fired whenShellBridge.handleMessagedrops an incoming postMessage it can't route to a registered napplet window.infois anUnroutedMessageInfo({ type?, origin, reason }) wherereasonis'no-source-window'or'unregistered-window'. The message is still dropped — this exists so otherwise-silent drops (e.g. an intent/srcdociframe whosecontentWindowwas never registered inoriginRegistry, or was swapped by a reload) are diagnosable instead of vanishing. Host canconsole.warninside its own hook; the bridge adds no console output and swallows hook errors so routing is never broken.
const bridge = createShellBridge({
...myShellAdapter,
onUnroutedMessage: ({ type, origin, reason }) => {
console.warn(`[shell] dropped ${type ?? '<unknown>'} from ${origin}: ${reason}`);
},
});Shell init
buildShellCapabilities— construct the current draftShellCapabilitiespayload emitted during theshell.ready/shell.inithandshake
Domain proxies (NIP-5D composition seams)
createIdentityProxy— interceptidentity.getProfile/getFollows/...trafficcreateThemeProxy— intercepttheme.get/theme.changedcreateKeysProxy— interceptkeys.bind/unbind/bindingscreateMediaProxy— interceptmedia.*playback controlcreateNotifyProxy— interceptnotify.send/list/read/dismiss
Keys forwarder
createKeysForwarder— host-keydown pump intokeys.forwardenvelopes; auto-attached bycreateShellBridge, also exported for hosts that manage their own forwarder instance
Session / origin registry
sessionRegistry— canonical windowId ↔ verified-napplet registry singletonnappKeyRegistry— deprecated alias forsessionRegistryoriginRegistry— origin-to-windowId map used by proxies and the keys-forwarderPendingUpdate— type for pending aggregate-hash change prompts
Manifest cache
manifestCache— browser-specific manifest cache singletonManifestCacheEntry— manifest cache entry type
Audio manager
audioManager— browser audio registry singleton (audio element pool)AudioSource— per-windowId audio source shape
Topic constants
TOPICS— canonical shell topic namespace for command routingTopicKey,TopicValue— typed topic lookup helpers
Types
Exported for host-app integration: ShellAdapter, ShellCapabilities, RelayPoolHooks, RelayPoolLike, RelayConfigHooks, WindowManagerHooks, AuthHooks, ConfigHooks, HotkeyHooks, WorkerRelayHooks, WorkerRelayLike, CryptoHooks, DmHooks, UploadHooks, IntentHooks, LinkHooks, CommonHooks, ListsHooks, SerialHooks, BleHooks, WebrtcHooks, SessionEntry, NappKeyEntry (deprecated), AclEntry, AclCheckEvent, UnroutedMessageInfo, ServiceDescriptor, ServiceHandler, ServiceRegistry, NostrEvent, NostrFilter, NappletMessage, ConsentRequest, and per-proxy *Deps/*Proxy interfaces.
Enforcement re-exports (from @kehto/runtime)
createEnforceGate, createNapEnforceGate, formatDenialReason, plus EnforceResult, EnforceConfig, NapEnforceConfig, IdentityResolver, AclChecker, NapMessage.
Compat re-exports (DRIFT-CORE-06)
Retained for migration consumers; new integrations should use current NIP-5D envelope types from @napplet/core. Slated for removal once upstream restores those exports.
Re-exported from @kehto/runtime: the v1.1 bus-kind enum, auth event kind, shell bridge URI constant, protocol version string, the full capability list, destructive-kind set, and the replay window seconds constant. Re-exported types cover the v1.1 capability union and bus-kind numeric union. See the typedoc API reference below for the exact identifier list.
API Reference
Full package docs: docs/packages/shell.md.
Generated API module: docs/api/modules/_kehto_shell.html (run pnpm docs:api).
License
MIT
