diff --git a/boltzr/src/config.rs b/boltzr/src/config.rs index cf7e579b..48292996 100644 --- a/boltzr/src/config.rs +++ b/boltzr/src/config.rs @@ -36,8 +36,8 @@ pub struct GlobalConfig { #[serde(rename = "otlpEndpoint")] pub otlp_endpoint: Option, - #[serde(rename = "mnemonicpath")] - pub mnemonic_path: Option, + #[serde(rename = "mnemonicpathEvm")] + pub mnemonic_path_evm: Option, pub postgres: crate::db::Config, pub rsk: Option, @@ -52,8 +52,8 @@ pub fn parse_config(path: &str) -> Result> { let mut config = toml::from_str::(fs::read_to_string(path)?.as_ref())?; trace!("Read config: {:#}", serde_json::to_string_pretty(&config)?); - if config.mnemonic_path.is_none() { - config.mnemonic_path = Some( + if config.mnemonic_path_evm.is_none() { + config.mnemonic_path_evm = Some( Path::new(path) .parent() .unwrap() diff --git a/boltzr/src/main.rs b/boltzr/src/main.rs index b7541bed..2c60126f 100644 --- a/boltzr/src/main.rs +++ b/boltzr/src/main.rs @@ -80,7 +80,7 @@ async fn main() { let refund_signer = if let Some(rsk_config) = config.rsk { Some( evm::refund_signer::LocalRefundSigner::new_mnemonic_file( - config.mnemonic_path.unwrap(), + config.mnemonic_path_evm.unwrap(), &rsk_config, ) .await diff --git a/lib/Boltz.ts b/lib/Boltz.ts index a4ea7bfb..1dea94a8 100644 --- a/lib/Boltz.ts +++ b/lib/Boltz.ts @@ -152,6 +152,7 @@ class Boltz { this.walletManager = new WalletManager( this.logger, this.config.mnemonicpath, + this.config.mnemonicpathEvm, walletCurrencies, this.ethereumManagers, ); diff --git a/lib/Config.ts b/lib/Config.ts index e630feb6..bdc23fec 100644 --- a/lib/Config.ts +++ b/lib/Config.ts @@ -40,7 +40,7 @@ type ChainConfig = { zmqpubhashblock?: string; // API endpoint of a MempoolSpace instance running on the chain of the configured client - // Comma seperated for multiple endpoints + // Comma separated for multiple endpoints mempoolSpace?: string; }; @@ -175,6 +175,7 @@ type ConfigType = { configpath: string; mnemonicpath: string; + mnemonicpathEvm: string; dbpath: string; postgres?: PostgresConfig; @@ -225,6 +226,7 @@ class Config { public static defaultConfigPath = 'boltz.conf'; public static defaultMnemonicPath = 'seed.dat'; + public static defaultMnemonicPathEvm = 'seed.dat'; public static defaultLogPath = 'boltz.log'; public static defaultDbPath = 'boltz.db'; @@ -239,13 +241,13 @@ class Config { constructor() { this.dataDir = getServiceDataDir('boltz'); - const { dbpath, logpath, configpath, mnemonicpath } = this.getDataDirPaths( - this.dataDir, - ); + const { dbpath, logpath, configpath, mnemonicpath, mnemonicpathEvm } = + this.getDataDirPaths(this.dataDir); this.config = { configpath, mnemonicpath, + mnemonicpathEvm, dbpath, logpath, @@ -505,6 +507,7 @@ class Config { return { configpath: path.join(dataDir, Config.defaultConfigPath), mnemonicpath: path.join(dataDir, Config.defaultMnemonicPath), + mnemonicpathEvm: path.join(dataDir, Config.defaultMnemonicPathEvm), dbpath: path.join(dataDir, Config.defaultDbPath), logpath: path.join(dataDir, Config.defaultLogPath), }; diff --git a/lib/cli/ethereum/EthereumUtils.ts b/lib/cli/ethereum/EthereumUtils.ts index 19ea9d2c..805ba95f 100644 --- a/lib/cli/ethereum/EthereumUtils.ts +++ b/lib/cli/ethereum/EthereumUtils.ts @@ -19,14 +19,16 @@ const getBoltzFilePath = (file: string): string => path.join(process.env.HOME!, '.boltz', file); const getBoltzWallet = (): HDNodeWallet => { - const filePath = getBoltzFilePath('seed.dat'); + for (const file in ['seed.dat', 'seedEvm.dat']) { + const filePath = getBoltzFilePath(file); - if (existsSync(filePath)) { - return Wallet.fromPhrase( - readFileSync(filePath, { - encoding: 'utf-8', - }).trim(), - ); + if (existsSync(filePath)) { + return Wallet.fromPhrase( + readFileSync(filePath, { + encoding: 'utf-8', + }).trim(), + ); + } } throw 'no Boltz wallet found'; diff --git a/lib/wallet/WalletManager.ts b/lib/wallet/WalletManager.ts index c3c2143d..c47cc3ab 100644 --- a/lib/wallet/WalletManager.ts +++ b/lib/wallet/WalletManager.ts @@ -59,6 +59,8 @@ class WalletManager { public wallets = new Map(); private readonly mnemonic: string; + private readonly mnemonicEvm: string; + private readonly slip77: Slip77Interface; private readonly masterNode: BIP32Interface; @@ -67,16 +69,13 @@ class WalletManager { constructor( private logger: Logger, mnemonicPath: string, + mnemonicPathEvm: string, private currencies: Currency[], public ethereumManagers: EthereumManager[], ) { - if (!fs.existsSync(mnemonicPath)) { - this.logger.info('Generated new mnemonic'); - - fs.writeFileSync(mnemonicPath, generateMnemonic()); - } - this.mnemonic = this.loadMnemonic(mnemonicPath); + this.mnemonicEvm = this.loadMnemonic(mnemonicPathEvm); + this.masterNode = bip32.fromSeed(mnemonicToSeedSync(this.mnemonic)); this.slip77 = slip77.fromSeed(this.mnemonic); } @@ -168,7 +167,7 @@ class WalletManager { } for (const manager of this.ethereumManagers) { - const ethereumWallets = await manager.init(this.mnemonic); + const ethereumWallets = await manager.init(this.mnemonicEvm); for (const [symbol, ethereumWallet] of ethereumWallets) { this.wallets.set(symbol, ethereumWallet); @@ -178,7 +177,9 @@ class WalletManager { private loadMnemonic = (filename: string) => { if (!fs.existsSync(filename)) { - throw Errors.NOT_INITIALIZED(); + this.logger.info(`Generated new mnemonic: ${filename}`); + + fs.writeFileSync(filename, generateMnemonic()); } const mnemonic = fs.readFileSync(filename, 'utf-8').trim(); diff --git a/test/integration/swap/UtxoNursery.spec.ts b/test/integration/swap/UtxoNursery.spec.ts index 9da6330a..93fb5001 100644 --- a/test/integration/swap/UtxoNursery.spec.ts +++ b/test/integration/swap/UtxoNursery.spec.ts @@ -75,6 +75,7 @@ describe('UtxoNursery', () => { const walletManager = new WalletManager( Logger.disabledLogger, mnemonicPath, + mnemonicPath, currencies, [], ); @@ -115,6 +116,7 @@ describe('UtxoNursery', () => { }, lockupTracker, {} as any, + {} as any, ); beforeAll(async () => { diff --git a/test/unit/wallet/WalletManager.spec.ts b/test/unit/wallet/WalletManager.spec.ts index 577906fa..423aa3e2 100644 --- a/test/unit/wallet/WalletManager.spec.ts +++ b/test/unit/wallet/WalletManager.spec.ts @@ -60,6 +60,7 @@ const mockedLndClient = >(LndClient); // TODO: test ethereum wallet initialization describe('WalletManager', () => { const mnemonicPath = 'seed.dat'; + const mnemonicPathEvm = 'seedEvm.dat'; const database = new Database(Logger.disabledLogger, ':memory:'); @@ -100,6 +101,7 @@ describe('WalletManager', () => { }; deleteFile(mnemonicPath); + deleteFile(mnemonicPathEvm); }; beforeAll(async () => { @@ -109,8 +111,15 @@ describe('WalletManager', () => { }); test('should initialize with a new menmonic and write it to the disk', () => { - new WalletManager(Logger.disabledLogger, mnemonicPath, currencies, []); + new WalletManager( + Logger.disabledLogger, + mnemonicPath, + mnemonicPathEvm, + currencies, + [], + ); expect(fs.existsSync(mnemonicPath)).toBeTruthy(); + expect(fs.existsSync(mnemonicPathEvm)).toBeTruthy(); }); test('should initialize a Bitcoin Core wallet when LND is not configured', async () => { @@ -124,6 +133,7 @@ describe('WalletManager', () => { const noLndWalletManager = new WalletManager( Logger.disabledLogger, mnemonicPath, + mnemonicPathEvm, currenciesNoLnd, [], ); @@ -149,6 +159,7 @@ describe('WalletManager', () => { const noLndWalletManager = new WalletManager( Logger.disabledLogger, mnemonicPath, + mnemonicPathEvm, currenciesNoLnd, [], ); @@ -161,6 +172,7 @@ describe('WalletManager', () => { walletManager = new WalletManager( Logger.disabledLogger, mnemonicPath, + mnemonicPathEvm, currencies, [], ); @@ -208,7 +220,14 @@ describe('WalletManager', () => { fs.writeFileSync(mnemonicPath, invalidMnemonic); expect( - () => new WalletManager(Logger.disabledLogger, mnemonicPath, [], []), + () => + new WalletManager( + Logger.disabledLogger, + mnemonicPath, + mnemonicPathEvm, + [], + [], + ), ).toThrow(WalletErrors.INVALID_MNEMONIC(invalidMnemonic).message); });