fix: defer wallet encryption key check so server starts without it
Move crypto key init from module-level throw to lazy getKey() — only errors when encrypt/decrypt are actually called. Downgrade env var check in index.ts from fatal exit to warning. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
f6eb7d2845
commit
673961580c
+18
-11
@@ -1,31 +1,38 @@
|
||||
import { createCipheriv, createDecipheriv, randomBytes } from 'crypto'
|
||||
|
||||
const ENCRYPTION_KEY_HEX = process.env.BOTFIGHTS_WALLET_ENCRYPTION_KEY
|
||||
let encryptionKey: Buffer
|
||||
let encryptionKey: Buffer | null = null
|
||||
|
||||
if (ENCRYPTION_KEY_HEX) {
|
||||
encryptionKey = Buffer.from(ENCRYPTION_KEY_HEX, 'hex')
|
||||
} else if (process.env.NODE_ENV === 'production') {
|
||||
throw new Error('CRITICAL: BOTFIGHTS_WALLET_ENCRYPTION_KEY not set. Cannot start in production.')
|
||||
} else {
|
||||
encryptionKey = randomBytes(32)
|
||||
console.warn('[crypto] WARNING: No BOTFIGHTS_WALLET_ENCRYPTION_KEY set. Generated random key — wallet data will be lost on restart.')
|
||||
function getKey(): Buffer {
|
||||
if (encryptionKey) return encryptionKey
|
||||
|
||||
const hex = process.env.BOTFIGHTS_WALLET_ENCRYPTION_KEY
|
||||
if (hex) {
|
||||
encryptionKey = Buffer.from(hex, 'hex')
|
||||
} else if (process.env.NODE_ENV === 'production') {
|
||||
throw new Error('BOTFIGHTS_WALLET_ENCRYPTION_KEY not set. Wallet operations unavailable.')
|
||||
} else {
|
||||
encryptionKey = randomBytes(32)
|
||||
console.warn('[crypto] WARNING: No BOTFIGHTS_WALLET_ENCRYPTION_KEY set. Generated random key — wallet data will be lost on restart.')
|
||||
}
|
||||
return encryptionKey
|
||||
}
|
||||
|
||||
export function encrypt(plaintext: string): string {
|
||||
const key = getKey()
|
||||
const iv = randomBytes(16)
|
||||
const cipher = createCipheriv('aes-256-gcm', encryptionKey, iv)
|
||||
const cipher = createCipheriv('aes-256-gcm', key, iv)
|
||||
const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()])
|
||||
const authTag = cipher.getAuthTag()
|
||||
return iv.toString('hex') + ':' + authTag.toString('hex') + ':' + encrypted.toString('hex')
|
||||
}
|
||||
|
||||
export function decrypt(ciphertext: string): string {
|
||||
const key = getKey()
|
||||
const [ivHex, authTagHex, encryptedHex] = ciphertext.split(':')
|
||||
const iv = Buffer.from(ivHex, 'hex')
|
||||
const authTag = Buffer.from(authTagHex, 'hex')
|
||||
const encrypted = Buffer.from(encryptedHex, 'hex')
|
||||
const decipher = createDecipheriv('aes-256-gcm', encryptionKey, iv)
|
||||
const decipher = createDecipheriv('aes-256-gcm', key, iv)
|
||||
decipher.setAuthTag(authTag)
|
||||
return decipher.update(encrypted) + decipher.final('utf8')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user