pre unlocked

This commit is contained in:
boufni95 2024-07-05 17:11:48 +02:00
parent b1af2997b0
commit 32dbd20a76
3 changed files with 43 additions and 17 deletions

View file

@ -1,9 +1,9 @@
import { InitWalletRequest } from "../../../proto/lnd/walletunlocker";
export const InitWalletReq = (secret: Buffer, cipherSeedMnemonic: string[]): InitWalletRequest => ({
export const InitWalletReq = (walletPw: Buffer, cipherSeedMnemonic: string[]): InitWalletRequest => ({
aezeedPassphrase: Buffer.alloc(0),
walletPassword: secret,
walletPassword: walletPw,
cipherSeedMnemonic,
extendedMasterKey: "",
extendedMasterKeyBirthdayTimestamp: 0n,

View file

@ -13,6 +13,7 @@ export type MainSettings = {
watchDogSettings: WatchdogSettings,
liquiditySettings: LiquiditySettings,
jwtSecret: string
walletPasswordPath: string
walletSecretPath: string
incomingTxFee: number
outgoingTxFee: number
@ -45,6 +46,7 @@ export const LoadMainSettingsFromEnv = (): MainSettings => {
liquiditySettings: LoadLiquiditySettingsFromEnv(),
jwtSecret: loadJwtSecret(storageSettings.dataDir),
walletSecretPath: process.env.WALLET_SECRET_PATH || getDataPath(storageSettings.dataDir, ".wallet_secret"),
walletPasswordPath: process.env.WALLET_PASSWORD_PATH || getDataPath(storageSettings.dataDir, ".wallet_password"),
incomingTxFee: EnvCanBeInteger("INCOMING_CHAIN_FEE_ROOT_BPS", 0) / 10000,
outgoingTxFee: EnvCanBeInteger("OUTGOING_CHAIN_FEE_ROOT_BPS", 60) / 10000,
incomingAppInvoiceFee: EnvCanBeInteger("INCOMING_INVOICE_FEE_ROOT_BPS", 0) / 10000,

View file

@ -55,12 +55,9 @@ export class Unlocker {
throw new Error("failed to get lnd info for reason: " + info.failure)
}
this.log("wallet is locked, unlocking...")
const secret = this.GetWalletSecret(false)
if (!secret) {
throw new Error("wallet secret not found to unlock wallet")
}
const unlocker = this.GetUnlockerClient(lndCert)
await unlocker.unlockWallet({ walletPassword: Buffer.from(secret, 'hex'), recoveryWindow: 0, statelessInit: false, channelBackups: undefined }, DeadLineMetadata())
const walletPassword = this.GetWalletPassword()
await unlocker.unlockWallet({ walletPassword, recoveryWindow: 0, statelessInit: false, channelBackups: undefined }, DeadLineMetadata())
const infoAfter = await this.GetLndInfo(ln)
if (!infoAfter.ok) {
throw new Error("failed to init lnd wallet " + infoAfter.failure)
@ -80,8 +77,9 @@ export class Unlocker {
console.log(seedRes.response.cipherSeedMnemonic)
console.log(seedRes.response.encipheredSeed)
this.log("seed created, encrypting and saving...")
const { encryptedData, secret } = this.EncryptWalletSeed(seedRes.response.cipherSeedMnemonic)
const req = InitWalletReq(secret, seedRes.response.cipherSeedMnemonic)
const { encryptedData } = this.EncryptWalletSeed(seedRes.response.cipherSeedMnemonic)
const walletPw = this.GetWalletPassword()
const req = InitWalletReq(walletPw, seedRes.response.cipherSeedMnemonic)
const initRes = await unlocker.initWallet(req, DeadLineMetadata(60 * 1000))
const adminMacaroon = Buffer.from(initRes.response.adminMacaroon).toString('hex')
const ln = this.GetLightningClient(lndCert, adminMacaroon)
@ -115,7 +113,7 @@ export class Unlocker {
}
EncryptWalletSeed = (seed: string[]) => {
return this.encrypt(seed.join('+'))
return this.encrypt(seed.join('+'), true)
}
DecryptWalletSeed = (data: { iv: string, encrypted: string }) => {
@ -129,8 +127,11 @@ export class Unlocker {
return Buffer.from(this.decrypt(data), 'hex')
}
encrypt = (text: string) => {
const sec = this.GetWalletSecret(true)
encrypt = (text: string, must = false) => {
const sec = this.GetWalletSecret(must)
if (!sec) {
throw new Error("wallet secret not found to encrypt")
}
const secret = Buffer.from(sec, 'hex')
const iv = crypto.randomBytes(16)
const cipher = crypto.createCipheriv('aes-256-cbc', secret, iv)
@ -138,13 +139,13 @@ export class Unlocker {
const cyData = cipher.update(rawData)
const encrypted = Buffer.concat([cyData, cipher.final()])
const encryptedData = { iv: iv.toString('hex'), encrypted: encrypted.toString('hex') }
return { encryptedData, secret }
return { encryptedData }
}
decrypt = (data: { iv: string, encrypted: string }) => {
const sec = this.GetWalletSecret(false)
if (!sec) {
throw new Error("wallet secret not found to decrypt seed")
throw new Error("wallet secret not found to decrypt")
}
const secret = Buffer.from(sec, 'hex')
const iv = Buffer.from(data.iv, 'hex')
@ -164,20 +165,43 @@ export class Unlocker {
this.log("the wallet secret file was not found")
}
if (secret === "" && create) {
this.log("creating wallet secret file")
secret = crypto.randomBytes(32).toString('hex')
fs.writeFileSync(path, secret)
}
return secret
}
GetWalletPassword = () => {
const path = this.settings.walletPasswordPath
let password = Buffer.alloc(0)
try {
password = fs.readFileSync(path)
} catch {
}
if (password.length === 0) {
this.log("no wallet password configured, using wallet secret")
const secret = this.GetWalletSecret(false)
if (secret === "") {
throw new Error("no usable password found")
}
password = Buffer.from(secret, 'hex')
}
return password
}
subscribeToBackups = async (ln: LightningClient, pub: string) => {
this.log("subscribing to channel backups for: ", pub)
const stream = ln.subscribeChannelBackups({}, { abort: this.abortController.signal })
stream.responses.onMessage((msg) => {
stream.responses.onMessage(async (msg) => {
if (msg.multiChanBackup) {
this.log("received backup, saving")
try {
const { encryptedData } = this.EncryptBackup(Buffer.from(msg.multiChanBackup.multiChanBackup))
this.storage.liquidityStorage.SaveNodeBackup(pub, JSON.stringify(encryptedData))
await this.storage.liquidityStorage.SaveNodeBackup(pub, JSON.stringify(encryptedData))
} catch (err: any) {
this.log("failed to save backup", err.message)
}
}
})
}