Application architecture
The application is a single Node.js service with a static browser client. The organization reflects runtime responsibilities rather than pretending each folder is an independent npm package.Runtime flow
src/server/index.jsloads local environment values and starts the HTTP server.src/server/app.jscomposes the API routers and servessrc/client.- The browser client creates signed paywall listings and submits them to the paywall API.
- Content is encrypted before it is persisted under the configured data directory.
- Download requests pass through payment verification and redemption tracking before content is decrypted.
Server modules
agent: demo agent client and its allowlisted runner endpoint.auth: public Privy configuration and retired legacy endpoints.config: environment loading, shared filesystem paths, and chain configuration.demo: demo-only monetized endpoints.facilitator: amount parsing, verification, settlement, receipts, and analytics.middleware: reusable HTTP 402 request handling.paywall: listing creation, metadata lookup, and protected downloads.vault: encrypted local storage and optional IPFS pinning.
src/server/config/paths.js owns project, client, and data paths. Feature modules should not calculate paths relative to their own source directories.
ROBINHOOD_NETWORK selects mainnet or testnet. The selected chain configuration is exposed to the browser through /api/privy/config, keeping wallet switching, checkout challenges, verification, explorer links, and UI labels aligned. Testnet storage is always isolated through ROBINHOOD_TESTNET_DATA_DIR or the default uploads-testnet directory.
Client modules
assets: images and icons copied as static files.integrations: source code for third-party browser integrations.generated: build output; never edit or commit it.scripts: browser behavior split into navigation, network, wallet, creator, checkout, and dashboard responsibilities.styles: ordered design-system, feature, dialog, and responsive styles loaded byapp.css.
scripts/app.js; feature behavior belongs in the matching responsibility file.
Tests
tests/regression.test.js runs without a live chain or funded wallet. Test names are grouped by production:, handshake:, paywall:, and browser: prefixes, with matching npm scripts.
tests/smoke/verify-link.js checks a running deployment and requires a paywall ID.
Persistent data
The default data directory remains<project>/uploads. Set X402_DATA_DIR to use another absolute or relative location. Back up the encrypted assets and the configured vault secret together.