Skip to content

feat(wallet-toolbox): let a host application mount StorageServer - #722

Closed
shruggr wants to merge 3 commits into
bsv-blockchain:mainfrom
shruggr:feat/storageserver-mountable
Closed

shruggr wants to merge 3 commits into
bsv-blockchain:mainfrom
shruggr:feat/storageserver-mountable

Conversation

@shruggr

@shruggr shruggr commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

What changed

StorageServer in @bsv/wallet-toolbox can be mounted inside a host Express application.

  • StorageServer.app is public. A host mounts it with hostApp.use('/storage', server.app) instead of calling start(). port is optional and only required by start(), which now throws WERR_INVALID_PARAMETER without it.
  • preRpcMiddleware?: RequestHandler[] runs on POST / after authentication, the authenticated rate limit and (when monetize is set) payment, immediately before JSON-RPC dispatch. Handlers see req.auth and the parsed body; a handler that responds stops the call before dispatch. It does not run on the action batch upload routes.
  • publicRoutes?: boolean (default true) controls the unauthenticated GET /, /robots.txt and /healthz routes.

With none of the new options set, the route stack is the same as before.

Why a host needs it

A host that serves wallet storage next to its own authenticated routes needs one listener, its own health and info routes, and a per-identity check (for example a storage quota) between authentication and dispatch. AuthFetch sends the BRC-104 handshake to the origin's /.well-known/auth, so under a sub-path the host answers the handshake with its own auth middleware, using the same wallet and the existing sessionManager option shared with the storage server. The README section covers this, including mount order relative to the host's auth middleware and body parsers.

Version

Minor: new public options and a public field. @bsv/wallet-toolbox, -client and -mobile move from the unpublished 2.14.5 to 2.15.0 in step, with the release notes, CHANGELOG, generated facts and baselines updated. StorageServer is only in the Node entry point; client and mobile bytes are unchanged. #719 (StorageKnex on Postgres) makes the same 2.14.5 → 2.15.0 bump; whichever merges second merges its notes into the 2.15.0 entries.

docs/storage.md is updated for the StorageServer entries only; a full pnpm doc run also rewrites unrelated sections and is left out.

Tests

New src/storage/remoting/__test/StorageServerMount.test.ts (SQLite StorageKnex):

  • mounts at /storage in a host app whose auth middleware handles the handshake with a shared SessionManager; StorageClient calls makeAvailable and findOrInsertUser through the mount
  • publicRoutes: false removes the GET routes; defaults keep them
  • start() without port throws
  • a preRpcMiddleware handler is not reached by an unauthenticated POST, sees req.auth.identityKey and the method when authenticated, returns 507 without dispatching, and lets dispatch proceed when it calls next()
  • without the option, dispatch is unchanged

Local results

  • pnpm lint, toolbox pnpm lint, toolbox pnpm typecheck: pass
  • pnpm format:check: pass
  • pnpm health:check: pass (0 contract findings)
  • npx jest --testPathIgnorePatterns='man.test.ts|live.test.ts|bench.test.ts|client/test|mobile/test' --watchman=false: 287/287 suites, 3115 passed, 1 skipped

No dependency or lockfile change. Nothing published.

Expose the configured Express application as StorageServer.app and make
port optional outside start(). Add preRpcMiddleware, run on POST / after
authentication, rate limiting and payment and before JSON-RPC dispatch,
and publicRoutes to drop the unauthenticated GET routes. Defaults are
unchanged.
@sonarqubecloud

sonarqubecloud Bot commented Oct 1, 2026

Copy link
Copy Markdown

@shruggr

shruggr commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Closing for now: running StorageServer standalone is enough for our deployment.

@shruggr shruggr closed this Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant