Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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
170 changes: 85 additions & 85 deletions mm2src/coins/eth/eth_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,94 +991,92 @@ fn test_get_enabled_erc20_by_contract_and_platform() {
const BNB_TOKEN: &str = "1INCH-BEP20";
const ETH_TOKEN: &str = "1INCH-ERC20";

let passphrase = "spice describe gravity federal blast come thank unfair canal monkey style afraid";
let conf = json!({
"coins": [{
"coin": "BNB",
"name": "binancesmartchain",
"fname": "Binance Coin",
"avg_blocktime": 3,
"rpcport": 80,
"mm2": 1,
"use_access_list": true,
"max_eth_tx_type": 2,
"required_confirmations": 3,
"protocol": {
"type": "ETH",
"protocol_data": {
"chain_id": 56
}
},
"derivation_path": "m/44'/60'",
"trezor_coin": "Binance Smart Chain",
"links": {
"homepage": "https://www.binance.org"
}
},{
"coin": BNB_TOKEN,
"name": "1inch_bep20",
"fname": "1Inch",
"rpcport": 80,
"mm2": 1,
"avg_blocktime": 3,
"required_confirmations": 3,
"protocol": {
"type": "ERC20",
"protocol_data": {
"platform": "BNB",
"contract_address": "0x111111111117dC0aa78b770fA6A738034120C302"
}
},
"derivation_path": "m/44'/60'",
"use_access_list": true,
"max_eth_tx_type": 2,
"gas_limit": {
"eth_send_erc20": 60000,
"erc20_payment": 110000,
"erc20_receiver_spend": 85000,
"erc20_sender_refund": 85000
}
},{
"coin": "ETH",
"name": "ethereum",
"fname": "Ethereum",
"rpcport": 80,
"mm2": 1,
"sign_message_prefix": "Ethereum Signed Message:\n",
"required_confirmations": 3,
"avg_blocktime": 15,
"protocol": {
"type": "ETH",
"protocol_data": {
"chain_id": 1
}
},
"derivation_path": "m/44'/60'"
},{
"coin": ETH_TOKEN,
"name": "1inch_erc20",
"fname": "1Inch",
"rpcport": 80,
"mm2": 1,
"avg_blocktime": 15,
"required_confirmations": 3,
"decimals": 18,
"protocol": {
"type": "ERC20",
"protocol_data": {
"platform": "ETH",
"contract_address": "0x111111111117dC0aa78b770fA6A738034120C302"
}
},
"derivation_path": "m/44'/60'"
}]
"coin": "BNB",
"name": "binancesmartchain",
"fname": "Binance Coin",
"avg_blocktime": 3,
"rpcport": 80,
"mm2": 1,
"use_access_list": true,
"max_eth_tx_type": 2,
"required_confirmations": 3,
"protocol": {
"type": "ETH",
"protocol_data": {
"chain_id": 56
}
},
"derivation_path": "m/44'/60'",
"trezor_coin": "Binance Smart Chain",
"links": {
"homepage": "https://www.binance.org"
}
},{
"coin": BNB_TOKEN,
"name": "1inch_bep20",
"fname": "1Inch",
"rpcport": 80,
"mm2": 1,
"avg_blocktime": 3,
"required_confirmations": 3,
"protocol": {
"type": "ERC20",
"protocol_data": {
"platform": "BNB",
"contract_address": "0x111111111117dC0aa78b770fA6A738034120C302"
}
},
"derivation_path": "m/44'/60'",
"use_access_list": true,
"max_eth_tx_type": 2,
"gas_limit": {
"eth_send_erc20": 60000,
"erc20_payment": 110000,
"erc20_receiver_spend": 85000,
"erc20_sender_refund": 85000
}
},{
"coin": "ETH",
"name": "ethereum",
"fname": "Ethereum",
"rpcport": 80,
"mm2": 1,
"sign_message_prefix": "Ethereum Signed Message:\n",
"required_confirmations": 3,
"avg_blocktime": 15,
"protocol": {
"type": "ETH",
"protocol_data": {
"chain_id": 1
}
},
"derivation_path": "m/44'/60'"
},{
"coin": ETH_TOKEN,
"name": "1inch_erc20",
"fname": "1Inch",
"rpcport": 80,
"mm2": 1,
"avg_blocktime": 15,
"required_confirmations": 3,
"decimals": 18,
"protocol": {
"type": "ERC20",
"protocol_data": {
"platform": "ETH",
"contract_address": "0x111111111117dC0aa78b770fA6A738034120C302"
}
},
"derivation_path": "m/44'/60'"
}],
"passphrase": passphrase
});

let ctx = MmCtxBuilder::new().with_conf(conf).into_mm_arc();
CryptoCtx::init_with_iguana_passphrase(
ctx.clone(),
"spice describe gravity federal blast come thank unfair canal monkey style afraid",
)
.unwrap();
CryptoCtx::init_with_iguana_passphrase(ctx.clone(), passphrase).unwrap();

let req_bnb_token = json!({
"urls":["https://bsc-dataseed1.binance.org","https://bsc-dataseed1.defibit.io"],
Expand Down Expand Up @@ -1117,6 +1115,7 @@ fn test_fee_history() {
fn test_gas_limit_conf() {
use mm2_test_helpers::for_tests::ETH_SEPOLIA_SWAP_CONTRACT;

let passphrase = "123456";
let conf = json!({
"coins": [{
"coin": "ETH",
Expand All @@ -1135,11 +1134,12 @@ fn test_gas_limit_conf() {
"erc20_receiver_spend": 130000,
"erc20_sender_refund": 110000
}
}]
}],
"passphrase": passphrase
});

let ctx = MmCtxBuilder::new().with_conf(conf).into_mm_arc();
CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "123456").unwrap();
CryptoCtx::init_with_iguana_passphrase(ctx.clone(), passphrase).unwrap();

let req = json!({
"urls":ETH_SEPOLIA_NODES,
Expand Down
12 changes: 5 additions & 7 deletions mm2src/coins/eth/eth_wasm_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fn pass() {
}

async fn init_eth_coin_helper() -> Result<(MmArc, MmCoinEnum), String> {
let passphrase = "spice describe gravity federal blast come thank unfair canal monkey style afraid";
let conf = json!({
"coins": [{
"coin": "ETH",
Expand All @@ -28,16 +29,13 @@ async fn init_eth_coin_helper() -> Result<(MmArc, MmCoinEnum), String> {
},
"rpcport": 80,
"mm2": 1,
"max_eth_tx_type": 2
}]
"max_eth_tx_type": 2,
}],
"passphrase": passphrase,
});

let ctx = MmCtxBuilder::new().with_conf(conf).into_mm_arc();
CryptoCtx::init_with_iguana_passphrase(
ctx.clone(),
"spice describe gravity federal blast come thank unfair canal monkey style afraid",
)
.unwrap();
CryptoCtx::init_with_iguana_passphrase(ctx.clone(), passphrase).unwrap();

let req = json!({
"urls":ETH_SEPOLIA_NODES,
Expand Down
4 changes: 4 additions & 0 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5137,6 +5137,10 @@ pub fn is_wallet_only_ticker(ctx: &MmArc, ticker: &str) -> bool {
///
/// * `req` - Payload of the corresponding "enable" or "electrum" RPC request.
pub async fn lp_coininit(ctx: &MmArc, ticker: &str, req: &Json) -> Result<MmCoinEnum, String> {
if ctx.is_no_login_mode() {
return ERR!("Cannot enable coins in no-login mode.");
}
Comment on lines 5139 to +5142
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need something similar in v2 activation methods?


let cctx = try_s!(CoinsContext::from_ctx(ctx));
{
let coins = cctx.coins.lock().await;
Expand Down
30 changes: 22 additions & 8 deletions mm2src/coins/rpc_command/offline_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ pub enum OfflineKeysError {
MissingPrefixValue { ticker: String, prefix_type: String },
#[display(fmt = "Invalid parameters: start_index and end_index are only valid for HD mode")]
InvalidParametersForMode,
#[display(fmt = "Cannot get private key in no-login mode.")]
NotAllowedInNoLoginMode,
}

#[derive(Debug, Clone)]
Expand All @@ -116,9 +118,10 @@ impl HttpStatusCode for OfflineKeysError {
Self::CoinConfigNotFound(_) => StatusCode::BAD_REQUEST,
Self::KeyDerivationFailed { .. } => StatusCode::INTERNAL_SERVER_ERROR,
Self::InvalidHdRange { .. } => StatusCode::BAD_REQUEST,
Self::HdRangeTooLarge => StatusCode::BAD_REQUEST,
Self::MissingPrefixValue { .. } => StatusCode::BAD_REQUEST,
Self::InvalidParametersForMode => StatusCode::BAD_REQUEST,
Self::HdRangeTooLarge | Self::NotAllowedInNoLoginMode | Self::InvalidParametersForMode => {
StatusCode::BAD_REQUEST
},
Self::ProtocolParseError { .. } => StatusCode::BAD_REQUEST,
}
}
Expand Down Expand Up @@ -507,7 +510,9 @@ async fn offline_iguana_keys_export_internal(

let prefix_values = extract_prefix_values(&ctx, &ticker, &coin_conf)?;

let passphrase = ctx.conf["passphrase"].as_str().unwrap_or("");
let passphrase = ctx.conf["passphrase"].as_str().ok_or_else(|| {
OfflineKeysError::Internal("Couldn't derive 'passphrase' from the KDF configuration.".to_owned())
})?;

let key_pair = {
match key_pair_from_seed(passphrase) {
Expand Down Expand Up @@ -645,6 +650,10 @@ pub async fn get_private_keys(
ctx: MmArc,
req: GetPrivateKeysRequest,
) -> Result<GetPrivateKeysResponse, MmError<OfflineKeysError>> {
if ctx.is_no_login_mode() {
return MmError::err(OfflineKeysError::NotAllowedInNoLoginMode);
}

let mode = req.mode.unwrap_or_else(|| {
if ctx.enable_hd() {
KeyExportMode::Hd
Expand Down Expand Up @@ -965,7 +974,8 @@ mod tests {
let ctx = MmCtxBuilder::new()
.with_conf(json!({
"coins": [btc_conf],
"rpc_password": "test123"
"rpc_password": "test123",
"passphrase": TEST_MNEMONIC,
}))
.into_mm_arc();

Expand Down Expand Up @@ -999,7 +1009,8 @@ mod tests {
let ctx = MmCtxBuilder::new()
.with_conf(json!({
"coins": [btc_conf],
"rpc_password": "test123"
"rpc_password": "test123",
"passphrase": TEST_MNEMONIC,
}))
.into_mm_arc();

Expand Down Expand Up @@ -1093,7 +1104,8 @@ mod tests {
let ctx = MmCtxBuilder::new()
.with_conf(json!({
"coins": [arrr_conf],
"rpc_password": "test123"
"rpc_password": "test123",
"passphrase": TEST_SEED,
}))
.into_mm_arc();

Expand Down Expand Up @@ -1154,15 +1166,17 @@ mod tests {
async fn test_eth_iguana_eip55_formatting() {
use mm2_test_helpers::for_tests::eth_dev_conf;

let passphrase = "test_passphrase_for_eip55";
let ctx = MmCtxBuilder::new()
.with_conf(json!({
"coins": [eth_dev_conf()],
"rpc_password": "test123"
"rpc_password": "test123",
"passphrase": passphrase,
}))
.into_mm_arc();

// Initialize with a test passphrase for Iguana mode
CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "test_passphrase_for_eip55").unwrap();
CryptoCtx::init_with_iguana_passphrase(ctx.clone(), passphrase).unwrap();

let req = GetPrivateKeysRequest {
coins: vec!["ETH".to_string()],
Expand Down
7 changes: 7 additions & 0 deletions mm2src/coins_activation/src/platform_coin_with_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ pub enum EnablePlatformCoinWithTokensError {
#[display(fmt = "WalletConnect Error: {_0}")]
WalletConnectError(String),
PlatformCoinMismatch,
#[display(fmt = "Cannot enable coins in no-login mode.")]
CannotEnableInNoLoginMode,
}

impl From<CoinConfWithProtocolError> for EnablePlatformCoinWithTokensError {
Expand Down Expand Up @@ -390,6 +392,7 @@ impl HttpStatusCode for EnablePlatformCoinWithTokensError {
| EnablePlatformCoinWithTokensError::FailedSpawningBalanceEvents(_)
| EnablePlatformCoinWithTokensError::WalletConnectError(_)
| EnablePlatformCoinWithTokensError::PlatformCoinMismatch
| EnablePlatformCoinWithTokensError::CannotEnableInNoLoginMode
| EnablePlatformCoinWithTokensError::UnexpectedTokenProtocol { .. } => StatusCode::BAD_REQUEST,
EnablePlatformCoinWithTokensError::Transport(_) => StatusCode::BAD_GATEWAY,
}
Expand Down Expand Up @@ -441,6 +444,10 @@ where
Platform: PlatformCoinWithTokensActivationOps,
EnablePlatformCoinWithTokensError: From<Platform::ActivationError>,
{
if ctx.is_no_login_mode() {
return MmError::err(EnablePlatformCoinWithTokensError::CannotEnableInNoLoginMode);
}
Comment on lines +447 to +449
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you did add the check for some of the v2 activation methods, but I think that we need it in the utxo v2 activation methods as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a main gateway for all the v2 activations?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a main gateway for all the v2 activations?

Apparently it's not, what the hell..? They live under the same module but not implement the activation traits...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any activation or private-key related logic that isn't explicitly handled will eventually be covered by this check so we don't need to add ifs all over the codebase.


if req.request.is_hw_policy() {
return MmError::err(EnablePlatformCoinWithTokensError::UnexpectedDeviceActivationPolicy);
}
Expand Down
4 changes: 4 additions & 0 deletions mm2src/mm2_core/src/mm_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ impl MmCtx {
self.conf["i_am_seed"].as_bool().unwrap_or(false)
}

pub fn is_no_login_mode(&self) -> bool {
self.conf["passphrase"].is_null() && self.conf["wallet_name"].is_null()
}

#[cfg(not(target_arch = "wasm32"))]
pub fn rpc_ip_port(&self) -> Result<SocketAddr, String> {
let port = match self.conf.get("rpcport") {
Expand Down
4 changes: 4 additions & 0 deletions mm2src/mm2_main/src/lp_native_dex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,10 @@ pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> {
pub async fn lp_init(ctx: MmArc, version: String, datetime: String) -> MmInitResult<()> {
info!("Version: {} DT {}", version, datetime);

if ctx.is_no_login_mode() {
info!("Running on no-login mode. Wallet operations will be unavailable.");
}

// Ensure the database root directory exists before initializing the wallet passphrase.
// This is necessary to store the encrypted wallet passphrase if needed.
#[cfg(not(target_arch = "wasm32"))]
Expand Down
Loading
Loading