Host-side software for nSealr signers.
The companion is not trusted with private keys. It constructs requests, moves them over the selected transport, verifies device responses, and bridges Nostr clients to hardware-backed signing.
The product goal is a universal secretless CLI/app for all nSealr routes: account labels, route selection, request construction, QR/USB/smartcard/ external transport helpers, policy proposal transport, signed-output verification, and audit export. The companion is not the authoritative policy store for persistent nSealr devices and must not store production signing material.
Browser extension, npm SDK, CLI, local app, local service, and full NIP-46 relay work are access surfaces over the same companion platform. They must reuse package-owned validation, policy scaffolding, transport, and response verification logic instead of creating separate signer implementations. The repository is intentionally a single TypeScript monorepo: one developer can ship multiple artifacts without synchronizing separate SDK, extension, service, or CLI repositories.
Feature availability per signer family is tracked in nSealr/specs at
vectors/features/signer-feature-matrix-v0.json. Companion packages should
consume those shared contracts instead of inventing solution-specific behavior:
when a feature is present on multiple signer implementations, the request,
review, approval, policy, transport, or response-verification behavior must
match the shared contract_id.
nsealr fixture verifyvalidates shared signing, trusted-review, review-display-frame, review-detail-page, QR review-transcript, NIP-46 payload, NIP-46 policy-file, NIP-46 connection URI, NIP-46 relay-event, NIP-46 relay-step, NIP-46 session lifecycle, NIP-46 session gate, account descriptor, policy profile, grant descriptor, policy-change review, policy-decision, source public-key proof, feature-matrix, and persistent-secret custody contract fixtures fromnSealr/specs, including NIP-46 permission policy checks, bridge decisions, implementation limits, feature conformance contracts, custom hardware-wallet custody gates, and invalid hardening vectors.nsealr policy review-changerenders deterministic review pages and an approval digest for a secretlessset_policyproposal. It does not approve the change, persist policy, create grants, or dispatch signer I/O.nsealr requestcreates signing requests from event templates and parameterless device requests forget_capabilities,get_public_key, andget_signing_status, with caller-supplied--request-idsupport for hardware traces.nsealr dev-signsigns requests with an explicit test-only software key.- Each reusable
packages/*module now has an explicit@nsealr/*package manifest, sourcesrc/index.tsentrypoint, and builtdistexport. Internal imports use those package entrypoints instead of deep relative paths so SDK, extension, service, and CLI code share the same boundaries. @nsealr/sdk-examplesis a private executable examples app that imports public packages through their built entrypoints and exercises request/QR, local-service, browser-provider, the@nsealr/sdk/browserfacade, and already-decrypted NIP-46 flows without importing test-only signing helpers.- Public package production-source imports are checked in CI so
@nsealr/*imports stay on reviewed public entrypoints/subpaths and cannot drift into private apps or test-only signer packages. @nsealr/clientdefines the first local companion service protocol and native-messaging frame codec plus the high-level local-service client used by future browser, SDK, desktop, and CLI callers. The implemented operations are intentionally secretless: service status, pairing intent generation, deterministic pairing-review projection, digest-bound manual approval into a grant, a strict secretless JSON grant-store contract for local approvals/revocations, digest-bound storage-location review and approval artifacts, secretless route selection, signer-request validation, signer-response verification, and a signer-dispatch boundary that is unavailable unless a host explicitly injects a dispatcher. Route selection, validation, dispatch, and verification require an explicit client grant; unpaired, revoked, expired, or operation-scoped clients are rejected before signer payload handling. The service request parser rejects unsupported top-level request fields and unsupported per-operationparamsfields before those operations run. Dispatch validates the request, selects the route, requires a matching external-review acknowledgement for display-lesssign_eventroutes, rejects that acknowledgement on trusted-review routes, calls only the injected route dispatcher, and verifies the signer response before returning it. Shared route-refusal fixtures now pin those refusal rules across every route-selection vector before any production signer driver exists. The high-level client also binds each operation to its expected result type, so a native-messaging host cannot satisfyrequest_pairingwith an unrelated valid service result.@nsealr/sdk/browseris the browser-safe public SDK subpath for extension and web callers. It exposes@nsealr/browser-provider,@nsealr/client/browser, and pure core/policy/protocol/QR/review helpers while leaving the broader SDK root, fixtures, transport adapters, and test-only signing out of browser runtime imports.nsealr local review-pairingrenders deterministic local-service pairing review metadata from a pairing intent. It validates the digest-bound intent and does not approve clients or write grant stores.nsealr local approve-pairingcreates a pairing approval artifact only when the caller supplies the reviewed pairing digest. It writes an approval JSON object, not a grant store, and does not contact signer transports.nsealr local review-storagerenders digest-bound storage-location review metadata for explicit grant/account/route-driver paths. It does not choose default paths, accept duplicated path options, write storage files, approve clients, or contact signers. Executable validation failures are printed as single-line CLI errors, not stack traces.nsealr local approve-storagecreates a storage-location approval artifact only when the caller supplies the reviewed storage digest. It still does not create, move, or activate storage files.nsealr local native-host manifest,plan-install,approve-install, andexecute-installexpose the browser native-host onboarding flow through the public companion CLI. Manifest rendering and install planning are dry-run artifact steps. Approval requires the reviewed install digest, execution rechecks that digest, writes only the reviewed manifest path withwrite_newsemantics, and produces a separate execution report.nsealr local grant-store append-approvalwrites a new explicit secretless grant-store artifact from a pairing approval only when a storage approval covers the requested read-only input path, if any, and new output path. It may extend a caller-supplied input store, but it never chooses a default path, overwrites an existing output file, or mutates the input file.nsealr local grant-store revoke-clientwrites a new explicit grant-store artifact with a latest-client revocation appended only when a storage approval covers the requested read-only input path and new output path. It keeps grant history intact, never overwrites an existing output file, and never mutates the input file.@nsealr/browser-providerdefines the first NIP-07 provider adapter over an injected companion backend and explicit client identity. It validatesgetPublicKeyandsignEventboundaries, converts event templates into nSealr signer requests, can use local-service route selection for the selected account public key, routessignEventthrough local-service dispatch, includes a browser native-messaging client adapter over explicitsendNativeMessage, reuses the shared local-service timeout/cancellation bounds from@nsealr/client, verifies signed responses, and stores no browser-side production keys.@nsealr/browser-extensionis a private app scaffold for extension-owned message parsing and provider-backed request handling. It currently accepts only internalget_public_keyandsign_eventrequests, validates provider outputs, derives local client identity from a sanitized sender page-origin context before provider selection, can compose that context with the native-messaging local-service provider path, can request a digest-bound pairing intent, deterministic pairing-review metadata, and deterministic browser-origin permission review and approval metadata for that identity, with approval bound to the reviewed local pairing digest, can normalize those already-approved origin artifacts into a deterministic secretless store contract for exact origin/extension/pairing-digest/method lookup without writing browser storage, creating grants, or dispatching signers, can render a pure origin-permission review card for future popup approval UX without performing storage, grant, provider-injection, or signer-dispatch side effects, can maintain the approved-origin store through deterministic upsert/revoke helpers, includes a browser-storage adapter over an explicit injected storage area for that secretless origin-permission store without reading global browser APIs or changing packaged manifest permissions, exposes private stdout-only origin-permission artifact commands for approval, empty-store creation, upsert, and revoke, can enforce either a static approved-origin store or an async injected store loader before provider selection so denied methods fail before native messaging, passes that gate through both the browser-like background adapter and packaged background entrypoint over explicit injected dependencies, includes a pure popup active-tab origin selector for future approval UI without storage, grants, manifest permission changes, or key material, routes extension-internal popup control messages for origin permission review and digest-confirmed approval through the background controller, with approval writing only through an explicitly injected storage adapter and still creating no grants, provider injection, signer dispatch, or key material, includes a pure active-tab origin permission review orchestrator that binds selected-tab origin, extension id, and app name to the returned review before any rendering or approval, includes a pure popup origin-permission view composer that renders that active-tab review through the existing approval card and refresh control and delegates storage-backed approval to injected controls without direct browser storage APIs, grants, provider injection, signer dispatch, or key material, includes a pure background-controller boundary over injected native messaging with optional response timeouts and request-scoped cancellation, includes a pure runtime-message adapter that maps raw browser sender metadata into the internal sender shape before the background controller is called, includes an injected runtimeonMessagelistener installer with explicit teardown and asynchronoussendResponsehandling, includes a pure page-provider boundary that maps NIP-07getPublicKeyandsignEventcalls to validated background requests and installs it only on an explicit target without overwriting an existing provider, includes a pure page-bridge envelope plus page-side requester adapter for future page/content-script messaging, includes a pure content-script bridge handler that binds page envelopes to an injected sender-aware background requester, includes a content-script runtime requester over an injected runtime-message sender with request cancellation, includes a content-script runtime bridge bootstrap that composes the window listener with that runtime requester, includes a pure content-window event adapter that checks page source/origin before that bridge handler is reached, includes an injected content-window message-listener installer with explicit teardown and injected response posting plus a response-poster adapter that posts only to reviewedpostMessagetargets and normalized page origins, includes a page-window bridge exchange that posts page requests and accepts only matching extension responses through an injected window-like target, has pure page-script provider bootstraps over either an injected bridge exchange or the injected page-window bridge, includes a pure page-script injection helper over explicit document and extension-URL resolver dependencies, includes a pure content-script entrypoint composer that joins page-script injection with the runtime bridge and cleans up partial installs, includes a content-script browser entrypoint adapter over explicit document/window/location/runtime dependencies, includes a page-script browser provider entrypoint adapter over explicit window/location dependencies, includes a background browser entrypoint adapter over explicitruntime.onMessageandruntime.sendNativeMessagedependencies, includes content-runtime API adapters that wrap reviewedruntime.getURLandruntime.sendMessagedependencies, uses one shared page-origin validator across page-window and content-window boundaries, can emit secretless pending/resolved/rejected/cancelled request-state snapshots for future UI without exposing event templates or key material, keeps the active pending-request set explicitly bounded, and can abort in-flight native messaging when that pending request is cancelled through extension-internal list/cancel control messages, includes a packaged action popup HTML plus popup entrypoint over injectedruntime.sendMessageso visible UI can list/cancel those secretless pending requests while showing request id, selected route account/type, timestamps, and explicit no-key/no-event payload state, and can build either the default minimal no-host-permission manifest or an opt-in explicit-origin content-script manifest profile. The content-script profile still omits host-permission fields, broad URL matches, extension storage, and provider grants by default. It can also build an explicit storage-backed origin-approval profile: that opt-in profile requestsactiveTabandstorage, resolves the active tab only after the user opens the action popup, loads the approved-origin store from the reviewed storage adapter, binds approvals to the browser runtime's actual extension id, and writes approvals only through the same digest-confirmed background control path. It can build an explicit developer package artifact only after route-config review/approval. Embedded-store content-script builds still require a reviewed extension id plus origin-permission store as secretless background gate data; storage-backed builds start from browser extension storage instead of embedding approvals and treat any build-time extension id as optional metadata only. The build result exposes the selected route, shared native-host name, manifest permissions, content-script origin, optional embedded extension id, local pairing digest, popup mode, activeTab usage, and origin-permission mode it packaged, while still not installing a browser extension, writing extension storage at build time, creating grants, dispatching signers, or holding key material. The package-owned verifier now requires the digest-bound package-plan review artifact before accepting a package-build result. It rejects background bundle drift from the selected route, native-host name, and origin-permission metadata, and popup bundle drift from the reviewedpopup_mode. It also rejects content-script and page-script bundle drift from their reviewed browser bridge/provider entrypoints, even when artifact file hashes are recomputed.@nsealr/clientexposes the shared local-client identity parser, including the browser-safe@nsealr/client/client-identitysubpath, used before pairing, route selection, signer-request validation, and response verification.@nsealr/sdkis the platform-neutral npm facade over curated browser, companion, protocol, policy, QR, review, and smartcard namespaces. It deliberately excludes private test signing, Node-only fixture loading, and host transport adapters.@nsealr/serviceis the private native-messaging host scaffold over@nsealr/client. It can process multiple length-prefixed service messages on one stdio session, returns deterministic native-frame errors, and accepts explicit in-memory authorization context in tests. It can also load explicit storage-approved read-only secretless grant/account and route-driver JSON files for developer and integration harnesses. Browser native-host onboarding artifacts are now exposed by the publicnsealr local native-hostCLI; the private service keeps equivalent JSON helpers only for service-level harness tests. Native-host manifest/install CLI singleton options reject duplicates before artifacts are rendered. Route-driver serial-line timing controls are bounded before dispatch, so driver files cannot configure unbounded response waits or ignored-log loops. It does not open relays, store keys, write grant/account files, install native-host manifests without that explicit approval execution, or contact signer transports by default.nsealr review-requestrenders deterministic review JSON, digest-bound screen-review pages, or complete constrained-display detail pages from a signing request for untrusted host-side previews and test harnesses.nsealr smartcard-sim-signexercises the smartcard APDU signing boundary with a test-only simulator from the private@nsealr/dev-signerpackage and requires--review-acknowledgedbefore sending the event id to the display-less signer.packages/smartcardincludes fake-reader PC/SC boundary tests that normalize malformed reader-list, setup, and APDU transmit failures without claiming real-card support.nsealr verify-responsechecks request ids, event template integrity, NIP-01 event ids, and BIP-340 Schnorr signatures.- Transport exchanges now apply the same successful
sign_eventverification before returning a signed event response, so serial/file/stdio adapters cannot hand invalid signatures to higher layers as accepted output. - Local-service dispatch additionally checks successful
get_public_keyandsign_eventresponses against the selected route public key before returning them, so a configured dispatcher cannot silently answer for a different account. - CLI request, dev-sign, and verify-response commands can read/write JSON or
v0
nsealr1:QR envelopes. packages/transportprovides the first signer transport contract plus file, JSON-lines stdio, and serial-frame adapters. The test-only development signer transport lives in private@nsealr/dev-signer, so production transport code does not depend on software signing helpers. The stdio adapter bounds response-line output and captured stderr before accepting or reporting external signer process results, and times out silent processes that do not emit a response.- The serial-line transport boundary can drive an injected newline-oriented port, normalize common serial line endings, ignore device log lines, and reuse the same serial-frame validation before a native USB/WebSerial binding exists.
SerialLineStreamPortadapts Node readable/writable streams into that newline-oriented port interface for dependency-free serial integration tests, while enforcing the shared v0 serial-frame byte limit on buffered lines.exchangeSerialLineRequestowns one-shot serial-line validation/open/close sequencing insidepackages/transport, so CLI and future native bindings do not duplicate the safety boundary.nsealr serial-frameexposes offline serial-frame request wrapping and response unwrapping helpers for ESP32 bring-up and lab captures. Response unwrapping can verify the original request before writing output, so captured frames cannot silently drift across request ids.nsealr serial-line exchangeis the CLI wrapper for that package-owned one-shot exchange. It opens a newline serial device path only after request validation, verifies the response before writing output, skips firmware log lines, and closes the stream-backed port after the exchange. It is a local USB-serial bring-up helper, not a browser/WebUSB or persistent signer session.nsealr nip46 decidewrites the bridge decision for an already-decrypted NIP-46 payload using explicit permission inputs or a read-only policy file. Approvedsign_eventinputs must be kind-scoped, for examplesign_event:1; broadsign_eventis requested-permission metadata only. It does not open relays, decrypt NIP-44 payloads, persist grants, or contact signer transports.nsealr nip46 review-connectwrites deterministic review pages for an already-decrypted NIP-46connectrequest. It shows the remote signer pubkey, whether a secret was provided, and requested permissions without echoing the secret value or approving the client.nsealr nip46 approve-connectwrites a digest-bound local approval artifact only after the reviewed connect digest is supplied back to the CLI. The artifact records noack, grant, relay session, signer dispatch, or secret.nsealr nip46 review-auth-challengewrites deterministic review pages for an already-decrypted NIP-46auth_urlrelay response step. It records the remote signer pubkey, client pubkey, and URL without opening the URL.nsealr nip46 approve-auth-challengewrites a digest-bound local approval artifact only after the reviewed auth challenge digest is supplied back to the CLI. The artifact records no URL opening,ack, grant, relay session, signer dispatch, persisted state, or secret.nsealr nip46 gate-session-requestwrites the deterministicconnect_ack_pendingresult for a decrypted request bound to an approved-but-unacknowledged session checkpoint. It does not use session permissions, open relays, acknowledgeconnect, or dispatch a signer.nsealr nip46 parse-connection-urireads abunker://ornostrconnect://token from a local file and writes descriptor-only metadata without echoing the shared secret value. It does not open relays, acknowledgeconnect, persist grants, or contact signer transports.nsealr nip46 verify-connection-token-responseverifies a decryptednostrconnect://token response against the original local token file. It writes only secretless metadata, discovers the remote signer pubkey from the response envelope, and does not open relays, acknowledgeconnect, create grants, dispatch signers, or persist session state.packages/qrimplements the v0nsealr1:QR envelope fromnSealr/specs, including malformed/padded/invalid-UTF-8/oversized rejection. Encoding applies the same static decoded-JSON byte limit as decoding, so the companion does not emit QR payloads that v0 receivers would immediately reject. It also implements the v0nsealr1a:animated QR frame set for larger valid payloads, with digest, frame checksum, ordering, and frame-count checks before JSON parsing.packages/framingimplements the first checksum-protected serial line frame draft for USB CDC and UART experiments, including shared frame-size limits on both decode and encode. The package is browser-runtime clean for future WebSerial/WebUSB work, but it is not part of@nsealr/sdk/browseruntil that access surface is reviewed.packages/protocolvalidates request/response shape, centralizes the companion copy of the shared v0 implementation limits, and validates capability discovery and signing-status responses, including rejection of contradictorysigning_enabled: truediagnostics that still report missing gates, disabled diagnostics that omit missing-gate reasons, and duplicated gate entries. Response request ids must use the same v0 profile as requests. Successful signed-event responses are also checked for shared integer-safety, content, and tag resource limits before they can be accepted.packages/reviewmirrors the shared trusted-review vector semantics for companion previews. It is not a trusted approval surface.- Serial transport tests cover both capability discovery and explicit signing-disabled scaffold responses.
packages/fixturesloads shared event, trusted-review, review-display-frame, review-detail-page, QR review-transcript, NIP-46 payload, NIP-46 policy-file, NIP-46 connection URI, NIP-46 relay-event, NIP-46 relay-step, NIP-46 session lifecycle, NIP-46 session gate, account-descriptor, policy-profile, grant-descriptor, policy-change review, policy-decision, route-selection, source-public-key-proof, access-surface, feature-matrix, persistent-secret custody contract, and smartcard vectors fromnSealr/specsfor companion, Raspberry QR vault, ESP32 firmware, custom hardware-wallet, and smartcard conformance tests.packages/policyparses secretless account descriptors, policy profiles, and grant descriptors, selects secretless account-route metadata, renders digest-bound policy-change review pages against explicit account, policy, and grant context, then evaluates policy-decision transcript vectors without a persistent grant store. It rejects unsupported descriptor fields, embedded private-key material, QR-vault automation, external NIP-46 nSealr-managed automation, wildcard/decrypt/export grants, and grant targets outside ESP32 USB/NIP-46 and custom hardware-wallet persistent policy routes before CLI or fixture-verification code can treat those records as valid. The v0 nSealr-managed grant menu is deliberately limited tosign_eventkind1; additional automated methods or event kinds must arrive through specs vectors and parser updates before access surfaces can expose them. NIP-06 account descriptors must carry a reviewed source fingerprint matching the QR vault import-review contract. These records describe resulting signing public keys and routes. Mnemonics, BIP-39 passphrase namespaces, standalonenseckeys, device slots, card slots, and external signers are key sources or routes, not production secrets kept by companion. Policy records are internal nSealr records, not Nostr events. Persistent-device account descriptors default to manual-only policy; scoped-automation vectors are conformance fixtures that require a device-reviewed policy-change proposal before they can become active policy. Policy-change review requires the proposal to match the selected account, current policy, proposed policy, and proposed grants before the CLI writes review output.packages/smartcardimplements the first APDU codec, provider-based PC/SC APDU transport boundary, andSmartcardSignerboundary against shared smartcard vectors, including APDU rejection status words. The codec rejects non-integer byte/status-word fields, non-Uint8Arraypayloads, and oversized short-APDU payloads before simulator or PC/SC transport. The test-only APDU simulator lives in private@nsealr/dev-signer, not in the publishable smartcard package. The PC/SC boundary validates transmit-result shape, response status bytes, response data shape, and response data bytes before constructing response APDUs, and rejects malformed reader-provider output before reader connection.packages/nip46implements the first decrypted NIP-46 payload bridge forget_public_key,sign_event, localping, localswitch_relaysno-change metadata, and nSealr response mapping. It also parsesconnectrequests into policy-review intents, deterministic review pages, and digest-bound local approval artifacts, validates requested permission strings, and owns the read-only policy-file parser used by the CLI. It can also parse officialbunker://andnostrconnect://connection tokens into descriptor-only metadata for later UX, validating relays, requested permissions, and client metadata while retaining only secret presence. It now parses NIP-46kind:24133relay event envelopes into sender/recipient/content metadata without decrypting NIP-44 content, opening relays, or dispatching to signers. It also evaluates metadata-only relay request steps and response steps after plaintext is supplied by a future decryption layer, returning bridge decisions or response-shape metadata, including auth challenge URL metadata without credentials or fragments, without relay I/O, grant creation, signer dispatch, URL opening, or session persistence. Relay event envelopes with signed fields are NIP-01 id checked and BIP-340 verified before metadata is accepted. Shared specs vectors now also pinapproved_pending_acksession checkpoints and a pending-session request gate that rejects signer dispatch withconnect_ack_pendinguntil a future acknowledged-session contract exists. They also pin the derived permission requirements, positive/negative permission checks, bridge decisions,connectreview pages, and invalid payload rejection for signer routing, local response routing,connectreview, and permission-denied responses. Relay transport, NIP-44 encryption,connectacknowledgement, persistent permission grants, and auth-flow UI remain future work.
- Complete the package-boundary freeze for future
@nsealr/*npm SDK publication with package README files, third-party import tests, semver, provenance, and release automation. Built JS/declaration artifacts, manifests, explicit entrypoints, deep-import audit, and test-only signer isolation are already in place. - Expand the local companion service boundary with pairing, origin/app
identity, deterministic request cancellation/timeout bounds, deterministic
errors, and real signer transport drivers behind the reviewed dispatch
boundary.
The pure package-level route selector, the local-service route-selection
operation, the first SDK wrapper, a deterministic pairing-review projection,
CLI pairing-review and digest-confirmed approval-artifact commands, a strict
persistent grant-store contract, a multi-message native-messaging host loop,
validated native-host manifest generation, explicit storage-approved
read-only service context loading, digest-bound native-host install
approval artifacts, explicit approval-bound native-host manifest writing,
and grant-gated
dispatch_signer_requestoperation are in place. Full approval UI, default production storage activation, production signer transport drivers, and localhost APIs need separate threat-model and implementation passes. - Browser extension / NIP-07 bridge packaging around the provider adapter so
getPublicKeyandsignEventroute through companion without storing production signing material. The package-level provider can already read the selected public key through local-service route selection and routesignEventthrough local-service dispatch, returning deterministic signer-unavailable errors until a real dispatcher is configured. The private extension scaffold now also has the sender/page-origin identity boundary and injected origin-permission storage adapter needed before content-script injection is considered. The packaged manifest still requests no storage permission by default; storage-backed popup approval is an explicit browser package profile. Browser package route configuration must name an explicit browser-dispatchable connected route type (esp32_usb_nip46,custom_hardware_wallet, or futureexternal_nip46); stateless QR vaults, display-less smartcards, and account-only route configs are rejected for this access surface. - Public npm SDK alpha after package APIs, docs, semver, provenance, and
third-party import tests are stable. Package README coverage and a
built-artifact consumer smoke are now part of
make ci; packed-tarball installation smoke is also part ofmake ci; synchronized package version, changelog, executable SDK examples, executable README snippets, and release/provenance policy are documented. The public API review is bound to the generated API-surface digest. SDK browser-provider examples consume the shared access-surface vector instead of carrying an ad hoc browser/local service contract. A digest-bound package release plan now lists exactly which public packages may be rehearsed, confirms trusted-publishing/provenance requirements, and keeps local npm publish disabled. A manual package release rehearsal workflow prepares checked tarball artifacts whose manifest carries the release-plan digest, byte counts, and SHA-256 digests without publishing to npm. - Full NIP-46 / Nostr Connect relay session handling with NIP-44 encryption, permissions, auth challenge UI, and relay I/O.
- WebUSB, HID, CDC, WebSerial, and persistent transport experiments.
- Real PC/SC reader smoke tests and NFC smartcard adapter work.
- TROPIC01 USB DevKit research adapter for the custom persistent-secret hardware-wallet family.
- Relay publish and response verification tools.
apps/: CLI, local service/native-messaging host, browser extension, desktop shell, and developer tools.packages/: reusable@nsealr/*SDK/core/protocol/review/qr/framing/ transport/NIP-46/policy/client/provider modules.docs/: implementation notes and usage guides.
Run the repository verification loop with:
make ciThe Makefile pins pnpm@10.33.4; it uses a global pnpm only when that exact
version is available and otherwise falls back to npm exec. Release helper
scripts also invoke pinned pnpm internally so direct script runs do not depend
on a stale global install.
Run the CLI from the workspace with:
pnpm nsealr --help
pnpm nsealr fixture verify --specs ../specs
pnpm nsealr request get-signing-status --request-id req-status-1 --out status-request.json
pnpm nsealr request sign-event --event-template template.json --out request.qr --output-format qr
pnpm nsealr review-request --request request.qr --request-format qr --out review.json
pnpm nsealr review-request --request request.qr --request-format qr --detail-pages --max-compact-line-chars 48 --out review-detail-pages.json
pnpm nsealr policy review-change --proposal policy-change-proposal.json --account account.json --current-policy manual-policy.json --proposed-policy scoped-policy.json --grant proposed-grant.json --out policy-change-review.json
pnpm nsealr local review-pairing --intent pairing-intent.json --out pairing-review.json
pnpm nsealr local approve-pairing --intent pairing-intent.json --reviewed-pairing-digest <digest-hex> --approved-at 1900000000 --out pairing-approval.json
pnpm nsealr local review-storage --grant-store "$PWD/local-grants.json" --grant-store-output "$PWD/local-grants-next.json" --out storage-review.json
pnpm nsealr local approve-storage --review storage-review.json --reviewed-storage-digest <digest-hex> --approved-at 1900000000 --out storage-approval.json
pnpm nsealr local native-host plan-install --browser chromium --host-path /Applications/nSealr/nsealr-service --manifest-path "$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts/dev.nsealr.companion.json" --extension-id <chromium-extension-id> --out native-host-plan.json
pnpm nsealr local native-host approve-install --plan native-host-plan.json --reviewed-install-digest <install-digest-hex> --approved-at 1900000000 --out native-host-approval.json
pnpm nsealr local native-host execute-install --approval native-host-approval.json --reviewed-install-digest <install-digest-hex> --out native-host-execution.json
pnpm nsealr local grant-store append-approval --approval pairing-approval.json --grant-store "$PWD/local-grants.json" --storage-approval storage-approval.json --updated-at 1900000001 --out "$PWD/local-grants-next.json"
pnpm nsealr local review-storage --grant-store "$PWD/local-grants-next.json" --grant-store-output "$PWD/local-grants-revoked.json" --out storage-revoke-review.json
pnpm nsealr local approve-storage --review storage-revoke-review.json --reviewed-storage-digest <digest-hex> --approved-at 1900000010 --out storage-revoke-approval.json
pnpm nsealr local grant-store revoke-client --grant-store "$PWD/local-grants-next.json" --storage-approval storage-revoke-approval.json --client-id <client-id-hex> --origin extension:nsealr --surface browser_extension --revoked-at 1900000020 --out "$PWD/local-grants-revoked.json"
pnpm nsealr nip46 decide --message nip46-message.json --permissions sign_event:1 --out decision.json
pnpm nsealr nip46 decide --message nip46-message.json --policy-file policy.json --out decision.json
pnpm nsealr nip46 review-connect --message nip46-connect.json --out connect-review.json
pnpm nsealr nip46 approve-connect --review connect-review.json --reviewed-connect-digest <connect-digest-hex> --approved-at 1900000001 --out connect-approval.json
pnpm nsealr nip46 gate-session-request --session session.json --event relay-event.json --message nip46-message.json --evaluated-at 1900000100 --out session-gate.json
pnpm nsealr smartcard-sim-sign --secret-key <test-only-hex> --request request.qr --request-format qr --review-acknowledged --approval-digest <approval-digest-hex> --out response.qr --output-format qrCompanion software and tooling are released under the MIT License unless a file says otherwise. Documentation content is intended to be reusable under the nSealr documentation policy.