@kehto/shell 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/dist/index.d.ts +22 -33
- package/dist/index.js +14 -4
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Browser adapter over @kehto/runtime — ShellBridge and domain proxies.
|
|
4
4
|
|
|
5
|
-
> **Alpha status:** Kehto is an early runtime
|
|
5
|
+
> **Alpha status:** Kehto is an early runtime toolkit for a draft NIP-5D
|
|
6
6
|
> protocol. NAP contracts and injected-domain behavior are still draft; treat
|
|
7
7
|
> this package as current implementation guidance.
|
|
8
8
|
|
|
@@ -15,7 +15,7 @@ pnpm add @kehto/shell
|
|
|
15
15
|
## Published Napplet Compatibility
|
|
16
16
|
|
|
17
17
|
`@kehto/shell` publishes against `@napplet/core` and `@napplet/nap`
|
|
18
|
-
`>=0.
|
|
18
|
+
`>=0.32.0 <0.33.0`. The installed core 0.32.0 / nap 0.32.0 contracts follow
|
|
19
19
|
NAP-INTENT authority `5ac0490461ca6fec2f0d2e45b4835cf9bc08de24`, napplet/web#199
|
|
20
20
|
source `3037200c932488f14f7f369b8583c39c9c16510a` / merge
|
|
21
21
|
`b3f0007867eac109fa4917fac9c285d3b7cc6155`, and Version Packages #198 release
|
|
@@ -30,7 +30,12 @@ The primary entry point is `createShellBridge()` — it owns the postMessage lis
|
|
|
30
30
|
Current draft behaviors this package enforces:
|
|
31
31
|
|
|
32
32
|
- The shell does not inject a host-provided nostr object into napplets — NIP-5D explicitly forbids napplet-visible signing. Napplets call `relay.publish` / `relay.publishEncrypted` and the shell mediates the signing flow internally (NIP-44 default, NIP-04 opt-in for encrypted envelopes).
|
|
33
|
-
- `
|
|
33
|
+
- `AuthHooks.getSigner(windowId?)` receives the originating iframe window ID
|
|
34
|
+
when the runtime can identify it. The shell forwards this optional context
|
|
35
|
+
without imposing a consent policy; host runtimes may ignore it or use it to
|
|
36
|
+
resolve their own identity-scoped signer decisions.
|
|
37
|
+
- `injectNappletNamespacePrelude()` implements the NIP-5D injected-domain bootstrap and mandatory NAP-SHELL shim: hosts prepend it to `srcdoc` outside verified artifact bytes, install the parent-bound `shell.init` receiver, emit one `shell.ready`, and expose callable NAP interfaces before authored scripts run. Optional namespaces are filtered to the bare-domain allowlist; `shell` is always retained. Published core 0.32.0 and shim 0.30.0 omit generic mandatory shell, so Kehto retains this host-owned prelude under NAP-SHELL `5ac0490461ca6fec2f0d2e45b4835cf9bc08de24` until an upstream correction is reviewed.
|
|
38
|
+
- The injected resource projection follows draft NAP-RESOURCE `9511232f69313aa7953d110e35d32cc28d506f66`: `bytes(url, { servers? })` carries advisory Blossom locations and `bytesMany(requests)` keeps each `{ url, servers? }` entry intact.
|
|
34
39
|
- `window.napplet.shell.supports(domain)` answers synchronously and locally from the cached first `shell.init` environment. It returns `false` before `shell.init`, for unknown values, and for domains that are not live and granted to that napplet; it never sends a support-query message.
|
|
35
40
|
- Five optional per-domain proxies — `createIdentityProxy`, `createThemeProxy`, `createKeysProxy`, `createMediaProxy`, `createNotifyProxy` — can be composed between napplet and runtime to intercept request traffic per NAP. They are NOT wired by default. Identity/theme proxy `emit()` compatibility members fail closed; hosts must deliver automatic changes through `ShellBridge.publishIdentityChanged()` / `publishTheme()`, which enforce live session, granted domain, and current ACL.
|
|
36
41
|
- `keys.forward` is napplet-to-shell only. Active napplets suppress locally-bound keys from `keys.bindings` before forwarding; shell-initiated action triggers use `keys.action`.
|
|
@@ -56,7 +61,7 @@ dispatch, and does not infer payload kinds. Runtime delivery supplies the
|
|
|
56
61
|
**runtime-attested dTag**; no caller sender is accepted, topic source exclusion
|
|
57
62
|
is runtime-owned, and IDs and payloads are opaque.
|
|
58
63
|
|
|
59
|
-
Merged NAP-INC and released `@napplet/nap@0.
|
|
64
|
+
Merged NAP-INC and released `@napplet/nap@0.32.0` both deliver one `IncEvent`
|
|
60
65
|
to `on(topic, callback)`.
|
|
61
66
|
|
|
62
67
|
For channels, runtime ACL checks are open-only rather than per-message. The
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { ALL_CAPABILITIES, AclChecker, Capability, ConsentRequest, EnforceConfig
|
|
|
3
3
|
import { NappletMessage, NostrEvent, NostrFilter } from '@napplet/core';
|
|
4
4
|
export { NappletMessage, NostrEvent, NostrFilter, TOPICS, TopicKey, TopicValue } from '@napplet/core';
|
|
5
5
|
import { Theme } from '@napplet/nap/theme/types';
|
|
6
|
+
import { ResourceBytesItem, ResourceBytesRequest as ResourceBytesRequest$1, ResourceInfo } from '@napplet/nap/resource/types';
|
|
7
|
+
export { ResourceInfo } from '@napplet/nap/resource/types';
|
|
6
8
|
|
|
7
9
|
/** NIP-5D identity metadata associated with a registered iframe window. */
|
|
8
10
|
interface OriginIdentity {
|
|
@@ -132,8 +134,15 @@ interface WindowManagerHooks {
|
|
|
132
134
|
interface AuthHooks {
|
|
133
135
|
/** Get the current user's pubkey, or null if not logged in. */
|
|
134
136
|
getUserPubkey(): string | null;
|
|
135
|
-
/**
|
|
136
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Get the NIP-07 compatible signer, or null if unavailable.
|
|
139
|
+
*
|
|
140
|
+
* The optional window ID lets a shell bind its own signer policy to the
|
|
141
|
+
* requesting napplet without imposing that policy in Kehto.
|
|
142
|
+
*
|
|
143
|
+
* @param windowId - Originating napplet window, when available
|
|
144
|
+
*/
|
|
145
|
+
getSigner(windowId?: string): any | null;
|
|
137
146
|
}
|
|
138
147
|
/** Hook for config. */
|
|
139
148
|
interface ConfigHooks {
|
|
@@ -1296,15 +1305,11 @@ declare function createNotifyProxy(deps: NotifyProxyDeps): NotifyProxy;
|
|
|
1296
1305
|
* @file internal-resource.ts
|
|
1297
1306
|
*
|
|
1298
1307
|
* Kehto-internal shell-side resource wire types. Per PROJECT.md Decision #31,
|
|
1299
|
-
* this is NOT a staging-ground duplicate of upstream `@napplet/nap/resource
|
|
1300
|
-
*
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1303
|
-
*
|
|
1304
|
-
* vocabularies (kehto: 4 codes `{denied, canceled, network-error, invalid-url}`;
|
|
1305
|
-
* upstream: 8 codes `{not-found, blocked-by-policy,
|
|
1306
|
-
* timeout, too-large, unsupported-scheme, decode-failed, network-error,
|
|
1307
|
-
* quota-exceeded}`).
|
|
1308
|
+
* this is NOT a staging-ground duplicate of upstream `@napplet/nap/resource`.
|
|
1309
|
+
* Canonical resource info, per-resource request, and result-item shapes are
|
|
1310
|
+
* imported from the published package. The remaining local envelopes retain
|
|
1311
|
+
* Kehto's legacy compatibility fields (`requestId`, `bodyBase64`, status, and
|
|
1312
|
+
* headers) alongside the current `id`, `blob`, and `mime` fields.
|
|
1308
1313
|
*
|
|
1309
1314
|
* `resource-service.ts` now emits both legacy single-fetch compatibility
|
|
1310
1315
|
* fields and the current upstream-compatible fields.
|
|
@@ -1315,20 +1320,12 @@ declare function createNotifyProxy(deps: NotifyProxyDeps): NotifyProxy;
|
|
|
1315
1320
|
* resource.bytes.result, resource.bytes.error,
|
|
1316
1321
|
* resource.bytesMany.result, resource.bytesMany.error
|
|
1317
1322
|
*/
|
|
1323
|
+
|
|
1318
1324
|
/**
|
|
1319
1325
|
* Unique id for correlating a `resource.bytes` request to its later result /
|
|
1320
1326
|
* error / cancel envelope.
|
|
1321
1327
|
*/
|
|
1322
1328
|
type ResourceRequestId = string;
|
|
1323
|
-
/** Advisory resource capability and policy limits disclosed by the runtime. */
|
|
1324
|
-
interface ResourceInfo {
|
|
1325
|
-
schemes: readonly {
|
|
1326
|
-
scheme: string;
|
|
1327
|
-
enabled: boolean;
|
|
1328
|
-
}[];
|
|
1329
|
-
maxBytes?: number;
|
|
1330
|
-
maxUrls?: number;
|
|
1331
|
-
}
|
|
1332
1329
|
/** Inbound: napplet asks for advisory resource policy and scheme support. */
|
|
1333
1330
|
interface ResourceInfoRequest {
|
|
1334
1331
|
type: 'resource.info';
|
|
@@ -1346,6 +1343,8 @@ interface ResourceBytesRequest {
|
|
|
1346
1343
|
/** Legacy Kehto correlation ID. */
|
|
1347
1344
|
requestId?: ResourceRequestId;
|
|
1348
1345
|
url: string;
|
|
1346
|
+
/** Advisory Blossom server locations. Ignored for other schemes. */
|
|
1347
|
+
servers?: readonly string[];
|
|
1349
1348
|
/** Optional subset of fetch init (method, headers). Body bytes are shell-proxy-internal. */
|
|
1350
1349
|
init?: {
|
|
1351
1350
|
method?: string;
|
|
@@ -1370,7 +1369,7 @@ interface ResourceCancelRequest {
|
|
|
1370
1369
|
interface ResourceBytesManyRequest {
|
|
1371
1370
|
type: 'resource.bytesMany';
|
|
1372
1371
|
id: ResourceRequestId;
|
|
1373
|
-
|
|
1372
|
+
requests: readonly ResourceBytesRequest$1[];
|
|
1374
1373
|
}
|
|
1375
1374
|
/**
|
|
1376
1375
|
* Outbound: successful fetch result.
|
|
@@ -1413,17 +1412,7 @@ interface ResourceBytesError {
|
|
|
1413
1412
|
/**
|
|
1414
1413
|
* Current NAP-RESOURCE bulk result item.
|
|
1415
1414
|
*/
|
|
1416
|
-
type ResourceBytesManyItem =
|
|
1417
|
-
url: string;
|
|
1418
|
-
ok: true;
|
|
1419
|
-
blob: Blob;
|
|
1420
|
-
mime: string;
|
|
1421
|
-
} | {
|
|
1422
|
-
url: string;
|
|
1423
|
-
ok: false;
|
|
1424
|
-
error: string;
|
|
1425
|
-
message?: string;
|
|
1426
|
-
};
|
|
1415
|
+
type ResourceBytesManyItem = ResourceBytesItem;
|
|
1427
1416
|
/**
|
|
1428
1417
|
* Outbound: ordered bulk fetch result.
|
|
1429
1418
|
*/
|
|
@@ -1463,4 +1452,4 @@ type ResourceInbound = ResourceInfoRequest | ResourceBytesRequest | ResourceByte
|
|
|
1463
1452
|
*/
|
|
1464
1453
|
type ResourceOutbound = ResourceInfoResult | ResourceInfoError | ResourceBytesResult | ResourceBytesError | ResourceBytesManyResult | ResourceBytesManyError;
|
|
1465
1454
|
|
|
1466
|
-
export { type AclCheckEvent, type AclEntry, type AclStore, type AudioManager, type AudioSource, type AuthHooks, type BleHooks, type BrowserDeps, type CapabilityHooks, type CommonHooks, type ConfigHooks, type CryptoHooks, type DmHooks, type HotkeyHooks, type IdentityProxy, type IdentityProxyDeps, type IntentHooks, type KeysProxy, type KeysProxyDeps, type LinkHooks, type ListsHooks, type ManifestCache, type ManifestCacheEntry, type MediaProxy, type MediaProxyDeps, type NappletNamespacePreludeOptions, type NotifyProxy, type NotifyProxyDeps, type OriginIdentity, type OriginRegistry, type ProxyOriginRegistry, type RelayConfigHooks, type RelayPoolHooks, type RelayPoolLike, type ResourceBytesError, type ResourceBytesManyError, type ResourceBytesManyItem, type ResourceBytesManyRequest, type ResourceBytesManyResult, type ResourceBytesRequest, type ResourceBytesResult, type ResourceCancelRequest, type ResourceErrorCode, type ResourceInbound, type
|
|
1455
|
+
export { type AclCheckEvent, type AclEntry, type AclStore, type AudioManager, type AudioSource, type AuthHooks, type BleHooks, type BrowserDeps, type CapabilityHooks, type CommonHooks, type ConfigHooks, type CryptoHooks, type DmHooks, type HotkeyHooks, type IdentityProxy, type IdentityProxyDeps, type IntentHooks, type KeysProxy, type KeysProxyDeps, type LinkHooks, type ListsHooks, type ManifestCache, type ManifestCacheEntry, type MediaProxy, type MediaProxyDeps, type NappletNamespacePreludeOptions, type NotifyProxy, type NotifyProxyDeps, type OriginIdentity, type OriginRegistry, type ProxyOriginRegistry, type RelayConfigHooks, type RelayPoolHooks, type RelayPoolLike, type ResourceBytesError, type ResourceBytesManyError, type ResourceBytesManyItem, type ResourceBytesManyRequest, type ResourceBytesManyResult, type ResourceBytesRequest, type ResourceBytesResult, type ResourceCancelRequest, type ResourceErrorCode, type ResourceInbound, type ResourceInfoError, type ResourceInfoRequest, type ResourceInfoResult, type ResourceOutbound, type ResourceRequestId, type SerialHooks, type SessionRegistry, type ShellAdapter, type ShellBridge, type ShellCapabilities, type ShellEnvironment, type ThemeProxy, type ThemeProxyDeps, type UnroutedMessageInfo, type UploadBackendLike, type UploadHooks, type WebrtcHooks, type WindowManagerHooks, type WorkerRelayHooks, type WorkerRelayLike, adaptHooks, audioManager, buildShellCapabilities, createIdentityProxy, createKeysProxy, createMediaProxy, createNotifyProxy, createShellBridge, createThemeProxy, injectNappletNamespacePrelude, manifestCache, nappKeyRegistry, originRegistry, renderNappletNamespacePrelude, resolveShellEnvironment, sessionRegistry };
|
package/dist/index.js
CHANGED
|
@@ -88,8 +88,8 @@ function createAuthAdapter(shellHooks) {
|
|
|
88
88
|
getUserPubkey() {
|
|
89
89
|
return shellHooks.auth.getUserPubkey();
|
|
90
90
|
},
|
|
91
|
-
getSigner() {
|
|
92
|
-
return shellHooks.auth.getSigner();
|
|
91
|
+
getSigner(windowId) {
|
|
92
|
+
return shellHooks.auth.getSigner(windowId);
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
95
|
}
|
|
@@ -2071,11 +2071,21 @@ function nappletNamespacePrelude(domains) {
|
|
|
2071
2071
|
}
|
|
2072
2072
|
function makeResource() {
|
|
2073
2073
|
const objectUrls = /* @__PURE__ */ new Set();
|
|
2074
|
-
const bytes = (url) => request({
|
|
2074
|
+
const bytes = (url, options) => request({
|
|
2075
|
+
type: "resource.bytes",
|
|
2076
|
+
url,
|
|
2077
|
+
...Array.isArray(options?.servers) ? { servers: Array.from(options.servers) } : {}
|
|
2078
|
+
}, "resource.bytes.result", (msg) => msg.blob);
|
|
2075
2079
|
return {
|
|
2076
2080
|
info: () => request({ type: "resource.info" }, "resource.info.result", (msg) => msg.info),
|
|
2077
2081
|
bytes,
|
|
2078
|
-
bytesMany: (
|
|
2082
|
+
bytesMany: (requests) => request({
|
|
2083
|
+
type: "resource.bytesMany",
|
|
2084
|
+
requests: Array.from(requests || [], (entry) => ({
|
|
2085
|
+
url: entry.url,
|
|
2086
|
+
...Array.isArray(entry.servers) ? { servers: Array.from(entry.servers) } : {}
|
|
2087
|
+
}))
|
|
2088
|
+
}, "resource.bytesMany.result", (msg) => Array.isArray(msg.items) ? msg.items : []),
|
|
2079
2089
|
bytesAsObjectURL(url) {
|
|
2080
2090
|
let objectUrl = "";
|
|
2081
2091
|
const handle = {
|