optionnally provide an external seed

usage: `PHOENIX_SEED="focus certain canvas rude exist sausage chuckle
forget bronze brown warm comic" ./phoenixd`
This commit is contained in:
pm47 2024-03-25 11:49:39 +01:00
parent 0432da38e5
commit f2b378484a
No known key found for this signature in database
GPG Key ID: E434ED292E85643A
3 changed files with 24 additions and 10 deletions

View File

@ -18,12 +18,15 @@ import com.github.ajalt.clikt.sources.MapValueSource
import com.github.ajalt.mordant.rendering.TextColors.*
import com.github.ajalt.mordant.rendering.TextStyles.bold
import fr.acinq.bitcoin.Chain
import fr.acinq.bitcoin.MnemonicCode
import fr.acinq.lightning.BuildVersions
import fr.acinq.lightning.Lightning.randomBytes32
import fr.acinq.lightning.LiquidityEvents
import fr.acinq.lightning.NodeParams
import fr.acinq.lightning.PaymentEvents
import fr.acinq.lightning.bin.conf.EnvVars.PHOENIX_SEED
import fr.acinq.lightning.bin.conf.LSP
import fr.acinq.lightning.bin.conf.PhoenixSeed
import fr.acinq.lightning.bin.conf.getOrGenerateSeed
import fr.acinq.lightning.bin.conf.readConfFile
import fr.acinq.lightning.bin.db.SqliteChannelsDb
@ -47,6 +50,7 @@ import fr.acinq.lightning.payment.LiquidityPolicy
import fr.acinq.lightning.utils.Connection
import fr.acinq.lightning.utils.msat
import fr.acinq.lightning.utils.sat
import fr.acinq.lightning.utils.toByteVector
import fr.acinq.phoenix.db.*
import io.ktor.http.*
import io.ktor.server.application.*
@ -69,6 +73,17 @@ fun main(args: Array<String>) = Phoenixd()
class Phoenixd : CliktCommand() {
private val confFile = datadir / "phoenix.conf"
private val seed by option("--seed", help = "Manually provide a 12-words seed", hidden = true, envvar = PHOENIX_SEED)
.convert { PhoenixSeed(MnemonicCode.toSeed(it, "").toByteVector(), isNew = false) }
.defaultLazy {
val value = getOrGenerateSeed(datadir)
if (value.isNew) {
terminal.print(yellow("Generating new seed..."))
runBlocking { delay(500.milliseconds) }
terminal.println(white("done"))
}
value
}
private val chain by option("--chain", help = "Bitcoin chain to use").choice(
"mainnet" to Chain.Mainnet, "testnet" to Chain.Testnet
).default(Chain.Mainnet, defaultForHelp = "mainnet")
@ -155,13 +170,8 @@ class Phoenixd : CliktCommand() {
@OptIn(DelicateCoroutinesApi::class)
override fun run() {
FileSystem.SYSTEM.createDirectories(datadir)
val (seed, new) = getOrGenerateSeed(datadir)
if (new) {
if (seed.isNew) {
runBlocking {
terminal.print(yellow("Generating new seed..."))
delay(500.milliseconds)
terminal.println(white("done"))
terminal.println()
terminal.println(green("Backup"))
terminal.println("This software is self-custodial, you have full control and responsibility over your funds.")
terminal.println("Your 12-words seed is located in ${FileSystem.SYSTEM.canonicalize(datadir)}, ${bold(red("make sure to do a backup or you risk losing your funds"))}.")
@ -215,7 +225,7 @@ class Phoenixd : CliktCommand() {
skipAbsoluteFeeCheck = false,
maxAllowedCredit = liquidityOptions.maxFeeCredit
)
val keyManager = LocalKeyManager(seed, chain, lsp.swapInXpub)
val keyManager = LocalKeyManager(seed.seed, chain, lsp.swapInXpub)
val nodeParams = NodeParams(chain, loggerFactory, keyManager)
.copy(
zeroConfPeers = setOf(lsp.walletParams.trampolineNode.id),

View File

@ -2,4 +2,5 @@ package fr.acinq.lightning.bin.conf
object EnvVars {
const val PHOENIX_DATADIR = "PHOENIX_DATADIR"
const val PHOENIX_SEED = "PHOENIX_SEED"
}

View File

@ -1,18 +1,21 @@
package fr.acinq.lightning.bin.conf
import fr.acinq.bitcoin.ByteVector
import fr.acinq.bitcoin.ByteVector32
import fr.acinq.bitcoin.MnemonicCode
import fr.acinq.lightning.Lightning.randomBytes
import fr.acinq.lightning.utils.toByteVector
import okio.FileSystem
import okio.Path
data class PhoenixSeed(val seed: ByteVector, val isNew: Boolean)
/**
* @return a pair with the seed and a boolean indicating whether the seed was newly generated
*/
fun getOrGenerateSeed(dir: Path): Pair<ByteVector, Boolean> {
fun getOrGenerateSeed(dir: Path): PhoenixSeed {
val file = dir / "seed.dat"
val (mnemonics, new) = if (FileSystem.SYSTEM.exists(file)) {
val (mnemonics, isNew) = if (FileSystem.SYSTEM.exists(file)) {
FileSystem.SYSTEM.read(file) { readUtf8() } to false
} else {
val entropy = randomBytes(16)
@ -20,5 +23,5 @@ fun getOrGenerateSeed(dir: Path): Pair<ByteVector, Boolean> {
FileSystem.SYSTEM.write(file) { writeUtf8(mnemonics) }
mnemonics to true
}
return MnemonicCode.toSeed(mnemonics, "").toByteVector() to new
return PhoenixSeed(seed = MnemonicCode.toSeed(mnemonics, "").toByteVector(), isNew = isNew)
}