feat: externalize Lightning.Pub configuration to environment variables
- Replace hardcoded DEV_CONFIG with environment variable loading - Add VITE_RELAY_URL for Nostr relay WebSocket URL - Add VITE_LIGHTNING_PUB_PUBKEY for Lightning.Pub's Nostr pubkey (required) - Add VITE_LIGHTNING_PUB_API_URL for HTTP API - Add VITE_ATM_PRIVATE_KEY for persistent ATM identity - Generate ephemeral identity if no private key configured - Update machine installation docs with correct env var names Environment variables: - VITE_RELAY_URL (default: ws://localhost:7777) - VITE_LIGHTNING_PUB_PUBKEY (required) - VITE_LIGHTNING_PUB_API_URL (default: http://localhost:1776) - VITE_ATM_PRIVATE_KEY (optional, generates ephemeral if not set) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
6371244b46
commit
c604aa501c
2 changed files with 75 additions and 37 deletions
|
|
@ -33,25 +33,37 @@ import type { ATMServices, ATMContext } from '@lamassu/state-machine'
|
||||||
// Check if we're in a browser environment
|
// Check if we're in a browser environment
|
||||||
const isBrowser = typeof window !== 'undefined'
|
const isBrowser = typeof window !== 'undefined'
|
||||||
|
|
||||||
// Development infrastructure configuration
|
/**
|
||||||
// In production, these would come from environment or secure config
|
* Lightning configuration from environment variables
|
||||||
// Use local network IP for testing from other devices (e.g., Shock Wallet on phone)
|
*
|
||||||
const LOCAL_IP = '192.168.1.122' // Change this to your machine's local IP
|
* Environment variables (prefix with VITE_ for Vite):
|
||||||
|
* - VITE_RELAY_URL: Nostr relay WebSocket URL
|
||||||
const DEV_CONFIG = {
|
* - VITE_LIGHTNING_PUB_PUBKEY: Lightning.Pub's Nostr pubkey (hex or npub)
|
||||||
// Lightning.Pub Nostr pubkey (from docker logs - check with: docker logs lamassu-lightning-pub | grep pubkey)
|
* - VITE_LIGHTNING_PUB_API_URL: Lightning.Pub HTTP API URL
|
||||||
lightningPubPubkey: '4be8e203a3341bb2b74a4dcbf8774e061437f63ec21af7ec3144c8d0a68e2f39',
|
* - VITE_ATM_PRIVATE_KEY: ATM's Nostr private key (hex or nsec)
|
||||||
// Local strfry relay - use local IP for cross-device testing
|
* - VITE_ADMIN_TOKEN: Lightning.Pub admin token (dev only)
|
||||||
relayUrl: `ws://${LOCAL_IP}:7777`,
|
*/
|
||||||
// Admin token for HTTP API (development only)
|
function loadLightningConfig() {
|
||||||
|
// Development defaults (local Docker infrastructure)
|
||||||
|
const defaults = {
|
||||||
|
relayUrl: 'ws://localhost:7777',
|
||||||
|
lightningPubPubkey: '',
|
||||||
|
lightningPubApiUrl: 'http://localhost:1776',
|
||||||
adminToken: 'lamassu-dev-admin-token',
|
adminToken: 'lamassu-dev-admin-token',
|
||||||
// Lightning.Pub HTTP API
|
atmPrivateKey: '',
|
||||||
lightningPubApiUrl: `http://${LOCAL_IP}:1776`,
|
}
|
||||||
// Fixed dev identity for testing (fund this pubkey in Lightning.Pub)
|
|
||||||
// In production, identity is loaded from secure storage
|
return {
|
||||||
devPrivateKey: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
|
relayUrl: import.meta.env.VITE_RELAY_URL || defaults.relayUrl,
|
||||||
|
lightningPubPubkey: import.meta.env.VITE_LIGHTNING_PUB_PUBKEY || defaults.lightningPubPubkey,
|
||||||
|
lightningPubApiUrl: import.meta.env.VITE_LIGHTNING_PUB_API_URL || defaults.lightningPubApiUrl,
|
||||||
|
adminToken: import.meta.env.VITE_ADMIN_TOKEN || defaults.adminToken,
|
||||||
|
atmPrivateKey: import.meta.env.VITE_ATM_PRIVATE_KEY || defaults.atmPrivateKey,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CONFIG = loadLightningConfig()
|
||||||
|
|
||||||
interface LightningServices {
|
interface LightningServices {
|
||||||
nostrClient: NostrClient
|
nostrClient: NostrClient
|
||||||
lightningPub: LightningPubClient
|
lightningPub: LightningPubClient
|
||||||
|
|
@ -75,27 +87,45 @@ type PaymentReceivedCallback = (preimage: string) => void
|
||||||
*/
|
*/
|
||||||
export async function initializeLightningServices(): Promise<LightningServices> {
|
export async function initializeLightningServices(): Promise<LightningServices> {
|
||||||
console.log('[Lightning] Initializing services...')
|
console.log('[Lightning] Initializing services...')
|
||||||
|
console.log('[Lightning] Relay URL:', CONFIG.relayUrl)
|
||||||
|
console.log('[Lightning] Lightning.Pub pubkey:', CONFIG.lightningPubPubkey || '(not configured)')
|
||||||
|
|
||||||
// Use fixed dev identity for testing (in production, load from secure storage)
|
// Validate required configuration
|
||||||
// This allows us to fund the account once and reuse across page reloads
|
if (!CONFIG.lightningPubPubkey) {
|
||||||
const identity = isBrowser ? loadIdentityFromHex(DEV_CONFIG.devPrivateKey) : generateIdentity()
|
throw new Error(
|
||||||
console.log('[Lightning] Machine identity:', identity.publicKey)
|
'[Lightning] VITE_LIGHTNING_PUB_PUBKEY is required. ' +
|
||||||
console.log('[Lightning] Fund this pubkey in Lightning.Pub for testing')
|
'Get it from: docker logs lamassu-lightning-pub | grep pubkey'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load or generate ATM identity
|
||||||
|
let identity: MachineIdentity
|
||||||
|
if (CONFIG.atmPrivateKey) {
|
||||||
|
// Use configured private key
|
||||||
|
identity = loadIdentityFromHex(CONFIG.atmPrivateKey)
|
||||||
|
console.log('[Lightning] Loaded ATM identity from config')
|
||||||
|
} else {
|
||||||
|
// Generate new identity (for development/testing)
|
||||||
|
identity = generateIdentity()
|
||||||
|
console.warn('[Lightning] No VITE_ATM_PRIVATE_KEY configured - generated ephemeral identity')
|
||||||
|
console.warn('[Lightning] Set VITE_ATM_PRIVATE_KEY for persistent identity across restarts')
|
||||||
|
}
|
||||||
|
console.log('[Lightning] ATM pubkey:', identity.publicKey)
|
||||||
|
|
||||||
// Create Nostr client
|
// Create Nostr client
|
||||||
const nostrClient = new NostrClient({
|
const nostrClient = new NostrClient({
|
||||||
relays: [{ url: DEV_CONFIG.relayUrl }],
|
relays: [{ url: CONFIG.relayUrl }],
|
||||||
identity,
|
identity,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Connect to relay
|
// Connect to relay
|
||||||
await nostrClient.connect()
|
await nostrClient.connect()
|
||||||
console.log('[Lightning] Connected to relay:', DEV_CONFIG.relayUrl)
|
console.log('[Lightning] Connected to relay:', CONFIG.relayUrl)
|
||||||
|
|
||||||
// Create Lightning.Pub client
|
// Create Lightning.Pub client
|
||||||
const lightningPub = new LightningPubClient({
|
const lightningPub = new LightningPubClient({
|
||||||
accountPubkey: DEV_CONFIG.lightningPubPubkey,
|
accountPubkey: CONFIG.lightningPubPubkey,
|
||||||
relays: [DEV_CONFIG.relayUrl],
|
relays: [CONFIG.relayUrl],
|
||||||
})
|
})
|
||||||
|
|
||||||
lightningPub.initialize(nostrClient, identity)
|
lightningPub.initialize(nostrClient, identity)
|
||||||
|
|
@ -105,8 +135,8 @@ export async function initializeLightningServices(): Promise<LightningServices>
|
||||||
const clink = new CLINKClient({
|
const clink = new CLINKClient({
|
||||||
nostrClient,
|
nostrClient,
|
||||||
identity,
|
identity,
|
||||||
operatorPubkey: DEV_CONFIG.lightningPubPubkey, // Use Lightning.Pub as operator for dev
|
operatorPubkey: CONFIG.lightningPubPubkey, // Use Lightning.Pub as operator for dev
|
||||||
relays: [DEV_CONFIG.relayUrl],
|
relays: [CONFIG.relayUrl],
|
||||||
})
|
})
|
||||||
|
|
||||||
// Callbacks for events
|
// Callbacks for events
|
||||||
|
|
@ -208,8 +238,8 @@ function createATMServices(
|
||||||
// so it must be Lightning.Pub's pubkey for it to receive and pay.
|
// so it must be Lightning.Pub's pubkey for it to receive and pay.
|
||||||
// The pointer identifies which Lightning.Pub user account pays (e.g., "atm")
|
// The pointer identifies which Lightning.Pub user account pays (e.g., "atm")
|
||||||
const ndebit = encodeNdebit({
|
const ndebit = encodeNdebit({
|
||||||
pubkey: DEV_CONFIG.lightningPubPubkey,
|
pubkey: CONFIG.lightningPubPubkey,
|
||||||
relay: DEV_CONFIG.relayUrl,
|
relay: CONFIG.relayUrl,
|
||||||
pointer: 'atm', // Lightning.Pub user identifier for the ATM account
|
pointer: 'atm', // Lightning.Pub user identifier for the ATM account
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -514,4 +544,4 @@ export function watchInvoice(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export { DEV_CONFIG }
|
export { CONFIG }
|
||||||
|
|
|
||||||
|
|
@ -119,16 +119,24 @@ See [Device Configuration](./device-configuration.md) for detailed configuration
|
||||||
The ATM needs to connect to a Lightning.Pub instance. Configure via environment:
|
The ATM needs to connect to a Lightning.Pub instance. Configure via environment:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Nostr relay URL
|
# Nostr relay WebSocket URL (required)
|
||||||
VITE_NOSTR_RELAY_URL=wss://your-relay.example.com
|
VITE_RELAY_URL=wss://your-relay.example.com
|
||||||
|
|
||||||
# Lightning.Pub public key
|
# Lightning.Pub's Nostr public key (required)
|
||||||
VITE_LIGHTNING_PUB_PUBKEY=npub1...
|
# Get from: docker logs lamassu-lightning-pub | grep pubkey
|
||||||
|
VITE_LIGHTNING_PUB_PUBKEY=4be8e203a3341bb2b74a4dcbf8774e061437f63ec21af7ec3144c8d0a68e2f39
|
||||||
|
|
||||||
# ATM keypair (generate with: npx @lamassu/nostr-client generate-keypair)
|
# Lightning.Pub HTTP API URL (optional, for admin operations)
|
||||||
VITE_ATM_NSEC=nsec1...
|
VITE_LIGHTNING_PUB_API_URL=https://lp.operator.com
|
||||||
|
|
||||||
|
# ATM's Nostr private key (recommended for persistent identity)
|
||||||
|
# Generate with: npx @lamassu/nostr-client generate-keypair
|
||||||
|
# If not set, a new ephemeral identity is generated on each restart
|
||||||
|
VITE_ATM_PRIVATE_KEY=0123456789abcdef...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Important:** The `VITE_LIGHTNING_PUB_PUBKEY` is required. Without it, the ATM cannot communicate with Lightning.Pub.
|
||||||
|
|
||||||
## Auto-Start on Boot
|
## Auto-Start on Boot
|
||||||
|
|
||||||
### Systemd Service
|
### Systemd Service
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue