A simple, file-system based UHRP (Universal Host Reference Protocol) host server. Stores files locally on disk and provides HTTP endpoints for UHRP data retrieval and storage.
A lightweight Node.js server with Express that implements UHRP storage and
metadata endpoints. Files are served publicly from the local object directory.
The raw PUT /put commit is HMAC-authorized; the upload, list, find, and renew
workflows require BRC-103 identity, and payment policy runs after
authentication.
Clients PUT files with authentication, retrieve files via public GET, and query metadata via POST /lookup.
| Type | Requirement |
|---|---|
| Database | None; filesystem-based storage |
| External services | Wallet Storage (WALLET_STORAGE_URL), ARC (optional for payment transactions) |
| ts-stack packages | @bsv/sdk, @bsv/auth-express-middleware, @bsv/payment-express-middleware, @bsv/wallet-toolbox-client |
| Method | Path | Purpose |
|---|---|---|
| GET/HEAD | Static object paths | Retrieve stored files (public) |
| PUT | /put | HMAC-authorized streaming object commit (64 MiB default ceiling) |
| POST | /quote | Public storage-price quote |
| POST | /upload | Authenticated upload authorization and payment workflow |
| GET | /list | List the authenticated uploader's objects |
| GET | /find | Find authenticated uploader metadata |
| POST | /renew | Authenticated ownership/payment renewal |
None.
| Variable | Required | Description |
|---|---|---|
| PRICE_PER_GB_MO | No | Monthly storage price per GB (e.g., 0.03) |
| HOSTING_DOMAIN | No | Public domain for server advertisement (e.g., localhost:8080 or https://uhrp.example.com) |
| BSV_NETWORK | No | Target blockchain network (e.g., mainnet or testnet) |
| WALLET_STORAGE_URL | No | Wallet storage endpoint for key derivation (e.g., https://store-us-1.bsvb.tech) |
| SERVER_PRIVATE_KEY | Yes | 256-bit hex private key for server identity |
| HTTP_PORT | No | Express server port (default: 8080) |
| NODE_ENV | No | development or production |
| UHRP_CORS_MODE | No | public (default), allowlist, or disabled |
| UHRP_CORS_ALLOWED_ORIGINS | No | Exact comma-separated origins in allowlist mode |
| UHRP_CORS_ALLOWED_HEADERS | No | Strict comma-separated browser request-header allowlist; omit for additive compatibility |
| UHRP_UPLOAD_MAX_BODY_BYTES | No | Raw /put ceiling (default 67108864) |
| UHRP_JSON_MAX_BODY_BYTES | No | JSON ceiling (default 262144) |
| TRUST_PROXY_HOPS | No | Exact trusted proxy hop count, 0 through 10 |
PUT /put validates authorization, expiry, declared size, and any
Content-Length before consuming the body. It streams into a private
same-filesystem temporary file, hashes incrementally, and uses exclusive
atomic linking so partial data and overwrites are never published.
See Public Service Edge Security for the complete endpoint threat model.
# Install dependencies
npm install
# Development with nodemon hot-reload
npm run dev
# Build TypeScript
npm run build
# Run production build
npm startFiles stored in ./public or configured data directory.
# Build and start
npm run build && npm start
# Or build the repository's digest-pinned, multi-stage Node 24 image
docker build -t uhrp-lite:local .
docker run -d \
-e SERVER_PRIVATE_KEY=<256-bit-hex> \
-e HOSTING_DOMAIN=https://uhrp.example.com \
-e HTTP_PORT=8080 \
-v uhrp_data:/app/public \
-p 8080:8080 \
uhrp-lite:localThe container runs as the unprivileged node user and probes /ready before
it is considered healthy. The service remains filesystem-based with no
external database; mount durable storage at /app/public.
None; stateless server with files stored directly on disk with JSON metadata.
GET /health and GET /healthz report process liveness.GET /ready returns 200 only after wallet-backed authentication and payment
middleware initialization completes.