Skip to content

Commit b9d85f6

Browse files
andreabadessoclaude
andcommitted
fix: regenerate lavamoat policy from production dependencies
The lavamoat policy was generated against dev node_modules, but both Docker and the recommended production setup use production-only dependencies. This caused runtime policy violations because: 1. Shared transitive packages resolve through different parent chains in dev vs production node_modules. 2. config.js is loaded dynamically via a computed require() in settings.js, so lavamoat never discovers yargs and its deps. Regenerated the policy from production dependencies using a shim that statically requires config.js so lavamoat discovers the full dependency graph. Added README instructions for running from source with production deps to match the policy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4523cd6 commit b9d85f6

File tree

6 files changed

+351
-60
lines changed

6 files changed

+351
-60
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: docker-smoke-test
2+
on:
3+
push:
4+
branches:
5+
- master
6+
- release-candidate
7+
- release
8+
pull_request:
9+
branches:
10+
- master
11+
- release-candidate
12+
- release
13+
jobs:
14+
smoke-test:
15+
runs-on: ubuntu-latest
16+
timeout-minutes: 10
17+
steps:
18+
- name: Checkout
19+
# https://github.com/actions/checkout/releases/tag/v4.1.7
20+
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
21+
22+
- name: Build Docker image
23+
run: docker build -t hathor-wallet-headless .
24+
25+
- name: Start container
26+
run: |
27+
docker run -d --name headless-test \
28+
-p 8000:8000 \
29+
-e HEADLESS_NETWORK=testnet \
30+
-e HEADLESS_SERVER=https://node1.testnet.hathor.network/v1a/ \
31+
-e HEADLESS_SEED_DEFAULT="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" \
32+
-e HEADLESS_API_KEY=ci_test_key \
33+
hathor-wallet-headless
34+
35+
- name: Wait for service to be ready
36+
run: |
37+
for i in $(seq 1 30); do
38+
if curl -sf -H "X-API-KEY: ci_test_key" http://localhost:8000/wallet/status > /dev/null 2>&1; then
39+
echo "Service is ready"
40+
exit 0
41+
fi
42+
sleep 1
43+
done
44+
echo "Service failed to start"
45+
docker logs headless-test
46+
exit 1
47+
48+
- name: Verify API responds
49+
run: |
50+
RESPONSE=$(curl -s -H "X-API-KEY: ci_test_key" http://localhost:8000/wallet/status)
51+
echo "Response: $RESPONSE"
52+
echo "$RESPONSE" | grep -q "X-Wallet-Id"
53+
54+
- name: Stop container
55+
if: always()
56+
run: docker stop headless-test || true

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,8 @@ xpub_from_seed: .script-build-dirs .run_xpub_from_seed .script-clean-dirs
8989
# Command: Derive multisig xPub from seed
9090
.PHONY: multisig_xpub_from_seed
9191
multisig_xpub_from_seed: .script-build-dirs .run_multisig_xpub_from_seed .script-clean-dirs
92+
93+
# Command: Regenerate LavaMoat policy from production dependencies
94+
.PHONY: lavamoat_policy
95+
lavamoat_policy:
96+
bash scripts/generate-lavamoat-policy.sh

README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,78 @@ A **headless wallet** is a wallet application whose interface is an API.
1212

1313
To know how to operate and use Hathor headless wallet, see [Hathor headless wallet at Hathor docs — official technical documentation of Hathor](https://docs.hathor.network/pathways/components/headless-wallet).
1414

15+
### Running with Docker
16+
17+
The easiest way to run the headless wallet is with Docker. Pre-built images are available on [Docker Hub](https://hub.docker.com/r/hathornetwork/hathor-wallet-headless):
18+
19+
```bash
20+
docker run -p 8000:8000 --env-file .env.headless hathornetwork/hathor-wallet-headless
21+
```
22+
23+
Where `.env.headless` contains your configuration (do not commit this file):
24+
25+
```
26+
HEADLESS_NETWORK=mainnet
27+
HEADLESS_SERVER=https://node1.mainnet.hathor.network/v1a/
28+
HEADLESS_SEED_DEFAULT=your seed words here
29+
HEADLESS_API_KEY=your_api_key
30+
```
31+
32+
### Running from source
33+
34+
Requirements: Node.js >= 22.0.0, npm >= 10.0.0.
35+
36+
```bash
37+
# Install all dependencies (needed for the build step)
38+
npm ci
39+
40+
# Copy and edit the configuration file
41+
cp config.js.template config.js
42+
# Edit config.js with your settings (seed, network, server, etc.)
43+
44+
# Build the project
45+
npm run build
46+
47+
# Remove dev dependencies so the runtime matches the LavaMoat policy
48+
rm -rf node_modules
49+
npm ci --only=production
50+
51+
# Run
52+
npm run start:lavamoat
53+
```
54+
55+
> **Note:** The [LavaMoat](https://github.com/LavaMoat/LavaMoat) security policy is generated against production dependencies. Dev dependencies change the dependency resolution paths, causing policy violations at runtime. That's why dev dependencies must be removed after building.
56+
57+
### Development
58+
59+
For local development without LavaMoat:
60+
61+
```bash
62+
npm ci
63+
cp config.js.template config.js
64+
# Edit config.js with your settings
65+
66+
# Run without LavaMoat (uses nodemon for auto-reload)
67+
npm run dev
68+
69+
# Or build and run without LavaMoat
70+
npm run start
71+
```
72+
73+
To test with LavaMoat locally, follow the [Running from source](#running-from-source) steps above.
74+
75+
### Regenerating the LavaMoat policy
76+
77+
When dependencies change, the LavaMoat policy must be regenerated. **Do not use `npm run lavamoat:policy`** — it generates the policy against dev dependencies, which won't work at runtime.
78+
79+
Instead, use the provided script that generates the policy against production dependencies inside Docker:
80+
81+
```bash
82+
make lavamoat_policy
83+
```
84+
85+
This requires Docker to be running. The script builds the project with the Docker config, spins up a container with production-only `node_modules`, and runs `lavamoat --autopolicy` inside it.
86+
1587
## Support
1688

1789
If after consulting the documentation, you still need **help to operate and use Hathor headless wallet**, [send a message to the `#development` channel on Hathor Discord server for assistance from Hathor team and community members](https://discord.com/channels/566500848570466316/663785995082268713).

0 commit comments

Comments
 (0)