Skip to content

@kehto/mocks ​

Deterministic, in-memory mock services for every napplet NAP domain — merged and draft alike — so a shell has data to work with while implementing a NAP, without a real relay, device, downloader, wallet, or language-model provider.

Alpha status: Kehto is an early runtime toolkit for a draft NIP-5D protocol. Draft NAP contracts change; each mock records the exact napplet/naps ref it was written against, and scripts/audit-naps.mjs reports drift. Treat mock envelopes as the shape at that ref, not as a stability guarantee.

Install ​

bash
pnpm add -D @kehto/mocks

Manifest Facts ​

FieldValue
Sourcepackages/mocks/package.json, packages/mocks/src/index.ts
Version0.1.1
Runtime entry./dist/index.js
Types entry./dist/index.d.ts
Side effectsfalse

Peer Dependencies ​

PackageRange
@napplet/core>=0.32.0 <0.39.0
@napplet/nap>=0.32.0 <0.38.0

Workspace dependencies: @kehto/runtime (ServiceHandler contract) and @kehto/acl (capability names).

Primary APIs ​

AreaExports
AggregatecreateMockNapEnvironment, createMockNapServices, MOCK_NAP_REGISTRY, MOCK_SOCIAL_DOMAINS, findMockDomain, mockShellEnvironmentDomains, createMockNostrStore, createMockStatePersistence
BuilderdefineMockService, pushToWindow, pushThrough, resultType, DEFAULT_CLOCK, DEFAULT_SCHEDULER
DeterminismcreateSeededRng, hashLabel, mockHex, mockPubkey, mockEventId, mockSignature
FixturesMOCK_ACCOUNTS, MOCK_EVENTS, MOCK_RELAYS, MOCK_RELAY_URLS, buildMockEvent, queryNostrEvents, matchesNostrFilter, LINUX_DISTROS, findLinuxDistro, searchLinuxDistros
Domain factoriescreateMock<Domain>Service per wire domain (table below), createMockStatePersistence for storage
TypesMockService, MockServiceOptions, MockControls, MockDomainEntry, MockDomainKind, NapSpecRef, MockClock, MockScheduler, MockRouteContext, MockServiceDefinition, per-domain Mock<Domain>State / Mock<Domain>Options / Mock<Domain>Service

Usage ​

ts
import { createShellBridge } from '@kehto/shell';
import { createMockNapEnvironment } from '@kehto/mocks';

const env = createMockNapEnvironment({ seed: 7 });
const bridge = createShellBridge({ ...hooks, services: env.services, statePersistence: env.statePersistence });
// list env.domains in the shell environment's capabilities.domains

env.get('torrent').mock.state();   // inspect
env.resetAll();                     // back to seeds (store and storage too)

Every mock accepts seed, clock, scheduler, and latencyMs; every mock exposes service.mock (state(), reset(), sent, routes, runtime) plus domain controls for pushes and progress. See skills/use-nap-mocks for shell integration and skills/maintain-nap-mocks for keeping the mocks in sync with napplet/naps.

Domains ​

Kinds: service is routed by the runtime's built-in dispatcher to serviceRegistry[domain]; extension is routed only when the handler declares messageCapabilities and the shell exposes the domain; adapter, runtime-owned, and posture have no service factory.

DomainNAPStatusSpec refKindRoutes / note
bleNAP-BLEdraftPR #62 @ b46b8691service7 routes
blossomNAP-BLOSSOMdraftPR #71 @ 5e74daa4extension13 routes
captureNAP-CAPTUREdraftPR #94 @ 438b3761extension6 routes
catalogNAP-CATALOGdraftPR #95 @ 1020ae53extension1 route
classNAP-CLASSdraftPR #16 @ 48282798extensionpush-only
class-1NAP-CLASS-1draftPR #17 @ b9128e0cpostureStrict baseline: connect-src 'none', no consent prompt, no grant state; the default class when no class-contributing NAP triggers, delivered as class.assigned { class: 1 }.
class-2NAP-CLASS-2draftPR #18 @ 45c9b12dpostureUser-approved explicit origins: connect-src limited to the granted origins after a first-load consent prompt keyed on (dTag, aggregateHash), refuse-to-serve on residual meta-CSP, denied napplets served as class 1.
commonNAP-COMMONdraftPR #67 @ 8cd0eae8service8 routes
configNAP-CONFIGdraftPR #14 @ bed9cb5bservice5 routes
connectNAP-CONNECTdraftPR #19 @ ec81a3a4runtime-ownedNAP-CONNECT defines no connect.* envelopes; grants are served as CSP connect-src plus a discovery meta tag. Use createMockConnectGate() and createMockLoopbackNetwork().
countNAP-COUNTdraftPR #69 @ 9353a0c6service1 route
cvmNAP-CVMdraftPR #31 @ 28cf1bdbservice7 routes
displayNAP-DISPLAYdraftPR #97 @ 2c2e1b5cextension2 routes
dmNAP-DMdraftPR #74 @ 2c4e4423service6 routes
fsNAP-FSdraftPR #88 @ bd1b9e91service14 routes
gamepadNAP-GAMEPADdraftPR #130 @ 0b28f77eservice2 routes
gitNAP-GITdraftPR #137 @ a73bf8deextension10 routes
hashtreeNAP-HASHTREEdraftPR #73 @ 67997706extension17 routes
identityNAP-IDENTITYmergedmaster @ 43cb3a4eservice9 routes
incNAP-INCmergedmaster @ 43cb3a4eruntime-ownedThe runtime routes inc.* topics and channels itself (packages/runtime/src/inc-handler.ts) and attests sender/peer from authenticated endpoints. Mocks cannot and must not fabricate INC deliveries; shells get INC for free from the runtime. MOCK_INC_TOPICS supplies topic strings for tests.
intentNAP-INTENTmergedmaster @ 43cb3a4eservice3 routes
keysNAP-KEYSdraftPR #9 @ 8869a4cfservice3 routes
linkNAP-LINKdraftPR #53 @ 50a2cd45service1 route
listsNAP-LISTSdraftPR #68 @ 7cf00cdbservice3 routes
llmNAP-LLMdraftPR #134 @ 3e10939cservice4 routes
locationNAP-LOCATIONdraftPR #125 @ 24d2039cextension4 routes
mediaNAP-MEDIAdraftPR #10 @ 7806f438service6 routes
meshNAP-MESHdraftPR #122 @ bf9a4722extension5 routes
motionNAP-MOTIONdraftPR #124 @ 3069a945extension3 routes
navigationNAP-NAVIGATIONdraftPR #126 @ 9a4b179eextension2 routes
notifyNAP-NOTIFYdraftPR #11 @ 67877ef6service5 routes
nzbNAP-NZBdraftPR #136 @ 3a426fe4extension7 routes
outboxNAP-OUTBOXdraftPR #32 @ 8865f73dservice6 routes
powNAP-POWdraftPR #39 @ d85b4252extension8 routes
relayNAP-RELAYdraftPR #2 @ 9f30b350service5 routes
resourceNAP-RESOURCEdraftPR #80 @ ae5b9c64service4 routes
serialNAP-SERIALdraftPR #61 @ 0c6e88abservice3 routes
shellNAP-SHELLmergedmaster @ 43cb3a4eruntime-ownedThe shell package owns shell.ready/shell.init (packages/shell/src/shell-ready.ts). A mock environment only needs capabilities.domains to list every mocked domain; use mockShellEnvironmentDomains(entries) to build that list.
soulseekNAP-SOULSEEKdraftPR #135 @ 892ed8d4extension14 routes
storageNAP-STORAGEdraftPR #3 @ 4f4cf0caadapterRuntime-served domain. Pass createMockStatePersistence() as statePersistence in the shell adapter; the runtime handles storage.get/set/remove/keys, identity scoping, instance scope, and quota.
systemNAP-SYSTEMdraftPR #64 @ 43a112dbextension8 routes
themeNAP-THEMEmergedmaster @ 43cb3a4eservice1 route
torrentNAP-TORRENTdraftPR #72 @ bc99787eextension17 routes
uploadNAP-UPLOADdraftPR #33 @ f5cc981eservice3 routes
valueNAP-VALUEdraftPR #30 @ e468764dextension3 routes
webrtcNAP-WEBRTCdraftPR #59 @ 69523e8cservice3 routes
workerNAP-WORKERdraftPR #107 @ 0a54af9aextension4 routes

Transfer-oriented mocks (torrent, nzb, soulseek, resource, upload, fs, blossom, hashtree, git) model Linux distribution images only.

Scope Boundaries ​

  • Shapes, not semantics: results and pushes follow the recorded NAP ref, with placeholder ids, signatures, bytes, and provider output. Nothing is cryptographically valid or fetched from the network.
  • Mocks never bypass runtime gates: built-in domains still require their ACL capability, extension domains still require the shell to expose the domain, and out-of-request pushes go through ServiceRuntimeContext.sendToEligibleNapplet when the service is registered. Extension mocks declare those push types as pushCapabilities (the pushes field of defineMockService). A push the runtime refuses is reported as false by pushToWindow and by domain controls such as class.assign(), and is never recorded in mock.sent.
  • Live subscription traffic (relay.event) is delivered through the send of the owning relay.subscribe request, exactly as the reference relay services do, so the runtime's liveness and relay:read checks apply and the registered relay mock owns fan-out: the publisher's own matching subscriptions receive the event and the runtime ring buffer adds no second copy.
  • The relay mock implements the runtime's planned-execution relay contract (planRelayOperation / executeRelayOperation). It opens no relay transport, so every plan is local-only with no relay URLs and needs no network approval. Execution is skipped once the approval signal has aborted.
  • INC and NAP-SHELL are served by the runtime and @kehto/shell; the package records their refs and offers helpers but does not fabricate their traffic.
  • Draft-tracking only: the registry mirrors napplet/naps master and open PR heads at the recorded shas. It does not define new protocol behavior; spec gaps are called out in each module header.
  • Not a replacement for @kehto/services: use the reference services when a real backend exists.

API Reference ​