-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.env.example
More file actions
464 lines (383 loc) · 17.3 KB
/
Copy path.env.example
File metadata and controls
464 lines (383 loc) · 17.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# ==========================================
# DONKEYRIDE OPERATOR CONFIGURATION
# ==========================================
# Copy this file to .env and configure your operator
# ==========================================
# OPERATOR IDENTITY
# ==========================================
# Your Nostr public key (npub format)
OPERATOR_PUBKEY=npub1...
# Your Nostr secret key (nsec format) - KEEP SECRET!
# Operator Nostr identity. Either form works:
# OPERATOR_NSEC=nsec1... (bech32)
# OPERATOR_PRIVKEY=<64 hex chars> (hex)
# Without a key the operator cannot sign ANY public events (stakes,
# settlements, announcements) and will say so loudly at boot.
OPERATOR_NSEC=nsec1...
# Your Lightning address for receiving operator fees
OPERATOR_LIGHTNING=operator@getalby.com
# Operator fee percentage. The code default is 0, and this file shipped
# 0.005 while calling it "the default" — so every operator who started the
# documented way (cp .env.example .env) silently took 0.5% of fares they
# never touched, contradicting /info.regulatory on their own server.
#
# A non-custodial operator cannot deduct a fee: the rider pays the provider
# directly and nothing passes through here. A fee above 0 is only meaningful
# for a licensed Mode-B operator that actually settles the money.
OPERATOR_FEE_PERCENT=0
# ==========================================
# OPERATOR POLICY (the operator decides)
# ==========================================
# This describes how THIS deployment runs. DonkeyRide does not issue a
# licence and does not decide which legal regime applies.
#
# open - community/unregulated/co-op style operation
# regulated - a firm/operator applying its own roster and local rules
# custom - any other operator-defined posture
OPERATOR_POLICY_MODE=open
# Who may go online and accept work through this operator:
# open anyone with a Nostr identity
# allowlist identity must be on OPERATOR_ALLOWED_DRIVERS
# credentials required declarations from the domain profile
# allowlist_and_credentials both of the above
OPERATOR_ADMISSION_MODE=open
# Comma-separated hex pubkeys or npubs. This is the operator's private
# roster and is never returned by /info or published to Nostr. A taxi firm
# can add identities after doing whatever checks its market requires.
OPERATOR_ALLOWED_DRIVERS=
# ephemeral - no historical operator database (default reference posture)
# durable - requires a working DATABASE_URL and fails closed without it
OPERATOR_RECORD_MODE=ephemeral
# Public operator-specific documents/contact, exposed in /info.policy.
OPERATOR_TERMS_URL=
OPERATOR_PRIVACY_URL=
OPERATOR_CONTACT=
# Default fiat currency for pricing rides (USD|EUR|GBP|KES, default GBP).
# Set KES if you serve Kenyan riders paying via M-Pesa or Tando — fares then
# display in shillings and the M-Pesa/Tando pay amount is exact.
DEFAULT_FIAT_CURRENCY=GBP
# Fare rate card. Defaults are quoted in USD and auto-converted to the ride
# currency, so fares are sane in any currency (incl. KES) with no extra config.
# Running a real market? Set these to YOUR currency's amounts and FARE_CURRENCY
# to match — then the numbers are used verbatim (no conversion).
# e.g. Kenya: FARE_BASE=200 FARE_PER_KM=100 FARE_PER_MINUTE=20 FARE_CURRENCY=KES
FARE_BASE=2.50
FARE_PER_KM=1.50
FARE_PER_MINUTE=0.30
FARE_CURRENCY=USD
# ==========================================
# PAYMENT PROVIDER SELECTION
# ==========================================
# Choose your primary payment provider:
# - cash: Record-only, fare settled face-to-face, operator never touches money
# - demo: Mock provider for non-production tests only
# The reference operator refuses lnd, btcpay, alby, cln and every unknown
# provider even if an environment variable claims the operator is licensed.
# Regulated custody belongs in a separately reviewed integration.
PAYMENT_PROVIDER=cash
# Optional fallback providers. The whole chain is validated before startup:
# only cash is allowed in production; demo may be added in development/tests.
PAYMENT_FALLBACKS=
# ==========================================
# ARCHIVED PROVIDER CONFIGURATION (NOT SELECTABLE BY REFERENCE OPERATOR)
# ==========================================
# LND gRPC host
LND_HOST=localhost:10009
# Path to TLS certificate
LND_CERT_PATH=/home/user/.lnd/tls.cert
# Path to macaroon file (needs invoice permissions)
LND_MACAROON_PATH=/home/user/.lnd/data/chain/bitcoin/mainnet/admin.macaroon
# Network (mainnet|testnet|regtest)
LND_NETWORK=mainnet
# ==========================================
# BTCPAY SERVER CONFIGURATION (Self-hosted)
# ==========================================
# BTCPay Server URL
BTCPAY_URL=https://btcpay.example.com
# BTCPay API key (from Server Settings -> Access Tokens)
BTCPAY_API_KEY=your_api_key_here
# BTCPay Store ID
BTCPAY_STORE_ID=your_store_id_here
# ==========================================
# ALBY CONFIGURATION (User-friendly Custodial)
# ==========================================
# Alby API key (from: https://getalby.com/developer)
ALBY_API_KEY=your_alby_api_key
# Optional: Alby refresh token for OAuth
ALBY_REFRESH_TOKEN=
# ==========================================
# CORE LIGHTNING CONFIGURATION (Trustless)
# ==========================================
# Path to lightning-rpc socket
CLN_SOCKET=/home/user/.lightning/bitcoin/lightning-rpc
# Network
CLN_NETWORK=bitcoin
# ==========================================
# SERVER CONFIGURATION
# ==========================================
# HTTP API port
PORT=3000
# WebSocket port
WS_PORT=3001
# ==========================================
# NOSTR RELAY CONFIGURATION
# ==========================================
# Comma-separated list of Nostr relays the OPERATOR publishes to (state
# snapshots, bond, heartbeat). Name your own — there is no fallback, and an
# empty value means nowhere, not "somewhere sensible".
#
# Prefer a relay you control. These are operator-signed events about other
# people's tasks, and a relay you do not run is one you cannot delete from,
# cannot rate-limit around, and cannot vouch for. Snapshots are sealed to
# your own key so a third party learns nothing from them, but there is still
# no reason to make someone else's disk your durability layer.
NOSTR_RELAYS=wss://relay.trotters.cc
# ==========================================
# WEB PUSH (job alerts, VAPID — no Firebase)
# ==========================================
# Generate once with `npx web-push generate-vapid-keys` and pin here.
# If unset, ephemeral keys are generated at boot (dev only — driver push
# subscriptions then die on every restart).
# VAPID_PUBLIC_KEY=
# VAPID_PRIVATE_KEY=
# Contact URL or mailto: for the push services
# VAPID_SUBJECT=mailto:operator@example.org
# ==========================================
# STAKE LIMITS
# ==========================================
# Minimum stake amount in satoshis
MIN_STAKE_AMOUNT=50
# Maximum stake amount in satoshis
MAX_STAKE_AMOUNT=10000
# Maximum daily stake volume in satoshis
MAX_DAILY_VOLUME=1000000
# ==========================================
# OPERATOR BOND (for trust)
# ==========================================
# Amount of satoshis you're bonding (publicly visible)
BOND_AMOUNT=1000000
# Bitcoin address holding your bond
BOND_ADDRESS=bc1q...
# Signature proving you control the bond address
BOND_PROOF=...
# ==========================================
# INSURANCE (optional)
# ==========================================
# Whether you provide insurance for user stakes
INSURANCE_ENABLED=false
# Insurance coverage amount in satoshis
INSURANCE_COVERAGE=100000
# Insurance provider
INSURANCE_PROVIDER=self
# ==========================================
# GEOGRAPHIC CONFIGURATION
# ==========================================
# Service area (for operator discovery)
# Format: lat,lon
SERVICE_LOCATION=40.7128,-74.0060
# Service radius in kilometers
SERVICE_RADIUS_KM=50
# Service area codes (for filtering)
# Format: Country-State/Province
SERVICE_AREAS=US-NY,US-NJ,US-CT
# ==========================================
# REPUTATION & TRUST
# ==========================================
# Require KYC for large amounts
REQUIRE_KYC=false
# KYC threshold in satoshis
KYC_THRESHOLD=100000
# ==========================================
# SECURITY
# ==========================================
# Enable NIP-98 authentication (recommended: true)
# When enabled, all mutating API routes require a signed NIP-98 header and
# lifecycle actions are role-checked (only the driver can complete, etc.)
#
# Leave this true. Without a signature there is no identity, so every
# participant-only check degrades to "anyone who knows the task id" — and
# task ids are not secret: the requester's kind 37500 announcement puts them
# on public relays for federated discovery. The server REFUSES to boot with
# NODE_ENV=production and auth disabled unless ALLOW_UNAUTHENTICATED=true.
ENABLE_NIP98_AUTH=true
# Escape hatch for a throwaway public demo with no real users. Never set
# this on a deployment carrying anyone's actual journeys.
# ALLOW_UNAUTHENTICATED=false
# Require the full signed URL (scheme + host) to match, not just the path.
# Leave false behind reverse proxies and the Vite dev proxy.
NIP98_STRICT_URLS=false
# Enable rate limiting (recommended: true)
ENABLE_RATE_LIMITING=true
# Runtime operator switching and cross-operator supply discovery need a PWA
# served by one operator to call another. Safe by default because the API
# uses no cookies and participant data still needs a NIP-98 signature.
# Set false to restrict browser callers to ALLOWED_ORIGINS.
FEDERATION_CORS=true
ALLOWED_ORIGINS=capacitor://localhost,http://localhost,https://localhost,http://localhost:5173
# ==========================================
# DISPATCH
# ==========================================
# Ride requests are only sent to drivers within this radius of the pickup
DISPATCH_RADIUS_KM=15
# When true, drivers who have not reported a location receive no requests
STRICT_DISPATCH=false
# How far a rider may move the pickup AFTER a driver has committed — a walk
# to a legal kerb, not a different job. Before anyone commits it is
# unlimited (and re-priced); after, the agreed fare never changes.
PICKUP_ADJUST_MAX_KM=1
# Favourite providers named on a request get the job to themselves for this
# long before it opens to every eligible driver
FAVOURITE_HEAD_START_MS=45000
# Free waiting after the provider marks arrival. Past it, the agreed fare
# grows at the rate card's per-minute rate — the operator still holds no
# money, it only recalculates what the two parties settle directly.
FREE_WAITING_MINUTES=3
# Scheduled (pre-booked) rides. A request with scheduled_for is browsable on
# the open list immediately but only enters live dispatch (WS broadcast +
# web push) this long before the pickup time; the same window triggers the
# reminder to both parties of an accepted booking.
SCHEDULE_DISPATCH_LEAD_MS=900000
# How far ahead a pickup may be booked (default 30 days)
SCHEDULE_MAX_ADVANCE_MS=2592000000
# Unmatched bookings are auto-cancelled this long after their pickup time
SCHEDULE_EXPIRE_GRACE_MS=3600000
# How often the scheduling sweep runs
SCHEDULE_SWEEP_MS=30000
# ==========================================
# NAVIGATION & ROUTING
# ==========================================
# Navigation provider: osrm, ors (OpenRouteService)
NAVIGATION_PROVIDER=osrm
# Fallback navigation providers (comma-separated)
NAVIGATION_FALLBACKS=osrm
# OSRM Configuration (free, no API key needed!)
# Point this at an operator-controlled OSRM instance. Empty falls back to
# localhost:5001; it never silently sends exact journeys to a public router.
OSRM_URL=
OSRM_PROFILE=car
OSRM_TRAFFIC=false
# Alternative private Valhalla backend. Setting NAVIGATION_PROVIDER=valhalla
# requires this URL; Valhalla precision-6 geometry is normalised internally.
VALHALLA_URL=
# Data boundary:
# blind — exact itinerary remains on participant devices and is exchanged
# after match with NIP-17; operator receives geohash-5 cells and
# client-routed distance/time totals only.
# managed — operator receives exact itinerary over authenticated HTTPS/WSS.
OPERATOR_DATA_MODE=blind
# Browser-reachable Valhalla base URL for blind mode (must expose POST /route).
PUBLIC_ROUTING_URL=/routing
# OpenRouteService Configuration (advanced features)
# Get API key from: https://openrouteservice.org/dev/#/signup
ORS_API_KEY=
ORS_URL=https://api.openrouteservice.org
ORS_PROFILE=driving-car
# Cost Optimization Parameters
FUEL_PRICE_PER_LITER=1.50
VEHICLE_EFFICIENCY=7.5
DRIVER_HOURLY_VALUE=15
TOLL_AVERSION=1.5
# Navigation Behavior
REROUTE_THRESHOLD=50
ETA_UPDATE_INTERVAL=60000
INSTRUCTION_ADVANCE_DISTANCE=200
# ==========================================
# DOCKER INFRASTRUCTURE
# ==========================================
# Database password (PostgreSQL)
DB_PASSWORD=changeme_secure_password
# Database URL (auto-configured in Docker)
# Managed operators may opt into durable storage deliberately:
# DATABASE_URL=postgresql://donkey:${DB_PASSWORD}@postgres:5432/donkeyride
# Redis URL (auto-configured in Docker)
REDIS_URL=redis://redis:6379
# Nostr Relay (use Docker service or external)
# For Docker: ws://nostr-relay:7777
# For external: wss://relay.damus.io
NOSTR_RELAY=ws://nostr-relay:7777
# OSRM URL (auto-configured in Docker)
OSRM_URL=http://osrm-backend:5000
# ==========================================
# DEVELOPMENT/TESTING
# ==========================================
# Set to 'development' for more verbose logging
NODE_ENV=production
# Enable debug logs
DEBUG=false
# ==========================================
# ADVANCED CONFIGURATION
# ==========================================
# Stake timeout (seconds before auto-release)
STAKE_TIMEOUT=86400
# Grace period for disputes (seconds)
DISPUTE_GRACE_PERIOD=3600
# Operator fee collection address
FEE_COLLECTION_ADDRESS=
# ==========================================
# EXAMPLE CONFIGURATIONS
# ==========================================
# Example 1: Cash Setup (Easiest — no custody, no credentials)
# --------------------------------------------------------------
# PAYMENT_PROVIDER=cash
# ==========================================
# NOTES
# ==========================================
# - Keep your OPERATOR_NSEC secret!
# - Production reference deployments must use PAYMENT_PROVIDER=cash
# - Commitments are reputational records, never held or forfeited money
# - Obtain written local advice before adding any custody or cancellation charge
# ==========================================
# PUBLIC ADVERTISEMENT (Nostr discoverability)
# ==========================================
# Relay URLs CLIENTS can reach (never Docker-internal hostnames). These are
# advertised in /info and in the operator's Kind 30511 announcement.
# PUBLIC_RELAY_URLS=wss://relay.example.com/relay,wss://relay.damus.io
# The operator's public HTTPS base URL, advertised as service_url.
# PUBLIC_BASE_URL=https://operator.example.com
# ==========================================
# WHAT THE OPERATOR LEAVES ON A RELAY
# ==========================================
# Kind 30078 state snapshots are the durability layer for the default
# database-free operator: on every task mutation the current state is
# published, and non-terminal tasks are rehydrated from them at boot.
#
# The body is SEALED to the operator's own key (NIP-44) — it has exactly one
# reader, this operator, and a relay stores it without being able to read it.
# Only the `d` tag (task id) and NIP-40 expiration are visible.
#
# An operator with DATABASE_URL set already has durable storage and can turn
# snapshots off entirely. Do NOT set this to false on a database-free
# deployment: active tasks would not survive a restart.
# NOSTR_SNAPSHOTS=true
# How coarse the location inside a snapshot is. 6 ≈ a 1.2 x 0.6 km cell.
# SNAPSHOT_GEOHASH_PRECISION=6
# SNAPSHOT_TTL_SECONDS=86400
# Publish a public kind 30535 receipt when a settlement completes. OFF by
# default: a public receipt is a permanent record that one pubkey paid
# another a named sum at a named time, and nothing here reads it back — both
# parties keep their own device-local history. When enabled the receipt
# carries no `p` tags, so it stays verifiable to whoever holds the task id
# without being indexed against either person.
# PUBLISH_PAYMENT_RECEIPTS=false
# ==========================================
# WHAT THE WEB APP LEAVES ON A RELAY
# ==========================================
# These are BUILD-TIME variables for the React app in web/, not operator
# settings — set them when you run `npm run web:build`, not here. They are
# documented alongside the operator's relay policy because they answer the
# same question: what ends up on a public relay.
# Publish the TROTT-02 kind 20500 availability beacon while a provider is on
# shift. OFF by default, and leave it off if an operator coordinates.
#
# The beacon is signed with the provider's DURABLE IDENTITY key — the key
# carrying their kind 0 name and every 30520 rating — and repeats every 60
# seconds for the whole shift, so `{kinds:[20500]}` is a live, named, rated
# feed of where a working person is. The ephemeral kind range stops relays
# STORING it; it does not stop a subscriber storing it.
#
# It buys nothing while an operator coordinates: dispatch already has the
# provider's position on the authenticated task socket, and nothing in this
# codebase subscribes to kind 20500. Turn it on only for operator-free
# peer-to-peer discovery, where the beacon's author is the contact address
# and there is no API to resolve a provider through.
# VITE_TROTT_P2P_BEACON=false