Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .envrc
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
use nix
if [ "$(uname -s)" = "Linux" ] && [ "$(uname -m)" = "x86_64" ]; then
use nix
else
echo "direnv: skipping Nix shell; supported only on x86_64 Linux." >&2
fi
3 changes: 2 additions & 1 deletion nix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ kept comment-free.
## Usage

- `nix-shell` — impure shell; auto-detects the host NVIDIA driver for GPU rendering.
- `direnv` — `.envrc` runs `use nix`, so the shell loads automatically on `cd`.
- `direnv` — `.envrc` runs `use nix` on x86_64 Linux, so the shell loads
automatically on `cd`. On other systems it intentionally does nothing.
- `nix develop` — pure flake shell; uses mesa software rendering (pure eval can't read
`/proc`). For GPU acceleration use `nix-shell`, or `nix develop --impure` with an
explicit `nvidiaVersion` (e.g. `"580.159.03"`).
Expand Down
10 changes: 10 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
in if m == null then null else builtins.elemAt m 1
}:

let
supportedSystem = pkgs.stdenv.hostPlatform.system == "x86_64-linux";
in
if supportedSystem then
let
prefixWrapper = from: tool: pkgs.writeShellScriptBin "x86_64-linux-gnu-${tool}"
''exec ${from}/bin/${tool} "$@"'';
Expand Down Expand Up @@ -134,3 +138,9 @@ pkgs.mkShell {
export XDG_DATA_DIRS="${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}:$XDG_DATA_DIRS"
'';
}
else
pkgs.mkShell {
shellHook = ''
echo "Skipping eigenwallet Nix dev shell; supported only on x86_64 Linux."
'';
}
80 changes: 77 additions & 3 deletions swap/src/cli/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,10 @@ pub use builder::ContextBuilder;
mod wallet {
use super::*;

// Legacy mode uses this Monero monitoring wallet and the seed.pem-derived
// Bitcoin wallet in the same CLI data directory.
const LEGACY_MONITORING_WALLET_NAME: &str = "swap-tool-blockchain-monitoring-wallet";

pub(super) async fn init_bitcoin_wallet(
electrum_rpc_urls: Vec<String>,
seed: &Seed,
Expand Down Expand Up @@ -925,12 +929,20 @@ mod wallet {
Ok(wallet)
}

fn legacy_wallet_path(data_dir: &Path) -> PathBuf {
data_dir.join(LEGACY_MONITORING_WALLET_NAME)
}

fn is_legacy_wallet_path(wallet_path: &str, legacy_data_dir: &Path) -> bool {
Path::new(wallet_path) == legacy_wallet_path(legacy_data_dir)
}

pub(super) async fn request_and_open_monero_wallet_legacy(
data_dir: &PathBuf,
env_config: EnvConfig,
daemon: &monero_sys::Daemon,
) -> Result<monero_sys::WalletHandle, Error> {
let wallet_path = data_dir.join("swap-tool-blockchain-monitoring-wallet");
let wallet_path = legacy_wallet_path(data_dir);

let wallet = monero::Wallet::open_or_create(
wallet_path.display().to_string(),
Expand Down Expand Up @@ -1056,6 +1068,20 @@ mod wallet {
SeedChoice::FromWalletPath { ref wallet_path } => {
let wallet_path = wallet_path.clone();

if is_legacy_wallet_path(&wallet_path, legacy_data_dir) {
let wallet = request_and_open_monero_wallet_legacy(
legacy_data_dir,
env_config,
daemon,
)
.await?;
let seed = Seed::from_file_or_generate(legacy_data_dir)
.await
.context("Failed to read legacy seed from file")?;

break (wallet, seed);
}

// Helper function to verify password
let verify_password = |password: String| -> Result<bool> {
monero_sys::WalletHandle::verify_wallet_password(
Expand Down Expand Up @@ -1148,7 +1174,7 @@ mod wallet {
.await?;
let seed = Seed::from_file_or_generate(legacy_data_dir)
.await
.context("Failed to extract seed from wallet")?;
.context("Failed to read legacy seed from file")?;

break (wallet, seed);
}
Expand All @@ -1175,14 +1201,62 @@ mod wallet {
.await?;
let seed = Seed::from_file_or_generate(legacy_data_dir)
.await
.context("Failed to extract seed from wallet")?;
.context("Failed to read legacy seed from file")?;

(wallet, seed)
}
};

Ok(wallet)
}

#[cfg(test)]
mod tests {
use super::*;
use bitcoin_wallet::BitcoinWalletSeed;

#[test]
fn detects_legacy_monitoring_wallet_path() {
let legacy_data_dir = PathBuf::from("/tmp/eigenwallet-mainnet");
let wallet_path = legacy_wallet_path(&legacy_data_dir);

assert!(is_legacy_wallet_path(
wallet_path.to_str().unwrap(),
&legacy_data_dir,
));
}

#[test]
fn does_not_treat_other_wallet_files_as_legacy() {
let legacy_data_dir = PathBuf::from("/tmp/eigenwallet-mainnet");
let wallet_path = "/tmp/eigenwallet/wallets/wallet_123";

assert!(!is_legacy_wallet_path(wallet_path, &legacy_data_dir));
}

#[tokio::test]
async fn legacy_seed_file_keeps_bitcoin_key_stable() {
let temp_dir = tempfile::tempdir().unwrap();

let legacy_seed = Seed::from_file_or_generate(temp_dir.path()).await.unwrap();
let legacy_key = legacy_seed
.derive_extended_private_key(bitcoin::Network::Bitcoin)
.unwrap();

let reread_legacy_seed = Seed::from_file_or_generate(temp_dir.path()).await.unwrap();
let reread_legacy_key = reread_legacy_seed
.derive_extended_private_key(bitcoin::Network::Bitcoin)
.unwrap();

let non_legacy_seed = Seed::from([0; crate::seed::SEED_LENGTH]);
let non_legacy_key = non_legacy_seed
.derive_extended_private_key(bitcoin::Network::Bitcoin)
.unwrap();

assert_eq!(legacy_key, reread_legacy_key);
assert_ne!(legacy_key, non_legacy_key);
}
}
}

pub mod data {
Expand Down
Loading