Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e39ff92
fix comment
mariocynicys Jun 14, 2025
facae9d
add a todo regarind session proposal response
mariocynicys Jun 14, 2025
638fe3f
add a todo related to ledger connection detection in wallet connect
mariocynicys Jun 14, 2025
a5b5909
rename send_proposal_request for clarity and add a todo
mariocynicys Jun 14, 2025
ab0edba
add a todo regarding a possible mis-use of session properties
mariocynicys Jun 15, 2025
42ddeb1
rename PersonalSign to EthPersonalSign to signify it's eth specific m…
mariocynicys Jun 15, 2025
fd0c6ab
add btc/utxo wallet connect method names
mariocynicys Jun 15, 2025
803d8f5
recognize that the conversion from PrivKeyBuildPolicy to the eth coun…
mariocynicys Jun 16, 2025
9799ec9
add a PrivKeyBuildPolicy::WalletConnect to be used for UTXO
mariocynicys Jun 17, 2025
72e845b
dont store address not pubkey in EthPrivKeyBuildPolicy::WalletConnect
mariocynicys Jun 18, 2025
9a03495
dont store address not pubkey in PrivKeyBuildPolicy::WalletConnect
mariocynicys Jun 18, 2025
3769d41
free UtxoCoinBuilder of the trait hell
mariocynicys Jun 18, 2025
bc796a2
impl wallet connection activation for btc
mariocynicys Jun 21, 2025
f15163f
add bip122 to WcChainId struct
mariocynicys Jun 21, 2025
735403d
merge with origin/dev
mariocynicys Jun 23, 2025
6dd49c1
fix ci clippy error
mariocynicys Jun 24, 2025
31d9edc
merge with origin dev
mariocynicys Jun 24, 2025
a665b55
strongtype wallet connect error
mariocynicys Jun 25, 2025
028ff49
move a note to a todo to not forget about it later
mariocynicys Jun 25, 2025
b892571
review(onur): rename the generic UtxoAddress struct
mariocynicys Jun 30, 2025
ca8e1a0
merge with origin/dev
mariocynicys Jul 2, 2025
2c72ad6
turn the TryFrom back to From
mariocynicys Jul 3, 2025
98f9d5f
manually convert PrivKeyBuildPoilcy to the ETH counterpart in legacy …
mariocynicys Jul 3, 2025
17bf308
refactor sign_message_hash for better usability
mariocynicys Jul 9, 2025
eee71ca
impl msg signing and pubkey recovery with walletconnect
mariocynicys Jul 9, 2025
16aa656
use signMessage for pubkey recovery as a fallback
mariocynicys Jul 9, 2025
f3451fe
fix error in activated_key_or_err() call when walletconnect is used
mariocynicys Jul 9, 2025
4587a1d
fix linting issues
mariocynicys Jul 9, 2025
af1cc4b
merge with origin/dev
mariocynicys Jul 10, 2025
c86a2bf
review(onur): add more spaces here and there for readability
mariocynicys Jul 10, 2025
87bb907
refine the todo regarding ledger connectino detection
mariocynicys Jul 14, 2025
480ad38
review(onur): rename build_..._iguana_secret to build_..._iguana_priv…
mariocynicys Jul 14, 2025
9bf308a
review(onur): reduce the size of `build_utxo_fields_with_walletconnec…
mariocynicys Jul 14, 2025
4149627
review(onur): use a specilizied struct for session_topic parameters (…
mariocynicys Jul 14, 2025
a22b14b
review(onur): let kdf_walletconnect-rust use &Topic instead of &str f…
mariocynicys Jul 14, 2025
35d7353
merge with origin/dev
mariocynicys Jul 25, 2025
f17f300
try to decode the signature response as hex first
mariocynicys Jul 28, 2025
6521246
move sign_message_hash to mm2_bitcoin
mariocynicys Jul 29, 2025
84f3f0b
review(shamardy): report the correct error when tron is used with wal…
mariocynicys Jul 30, 2025
e893297
review(shamardy): move chain_id inside protocol data for utxo
mariocynicys Jul 30, 2025
33868a6
Merge remote-tracking branch 'origin/dev' into btc-walletconnect
mariocynicys Jul 30, 2025
f0719d6
merge with origin/dev
mariocynicys Jul 30, 2025
821a5dd
fix failing tests
mariocynicys Jul 30, 2025
188424a
actually fix tests
mariocynicys Jul 30, 2025
0947655
merge with origin/dev
shamardy Jul 31, 2025
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
2 changes: 1 addition & 1 deletion mm2src/coins/eth/v2_activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ pub(crate) async fn build_address_and_priv_key_policy(
},
EthPrivKeyBuildPolicy::WalletConnect { session_topic } => {
let wc = WalletConnectCtx::from_ctx(ctx).map_err(|e| {
EthActivationV2Error::WalletConnectError(format!("Failed to get WalletConnect context: {}", e))
EthActivationV2Error::WalletConnectError(format!("Failed to get WalletConnect context: {e}"))
})?;
let chain_spec = chain_spec.ok_or(EthActivationV2Error::ChainIdNotSet)?;
let chain_id = chain_spec.chain_id().ok_or(EthActivationV2Error::UnsupportedChain {
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/hd_wallet/pubkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ where
.or_mm_err(|| HDExtractPubkeyError::HwContextNotInitialized)?;

let trezor_message_type = match coin_protocol {
CoinProtocol::UTXO => TrezorMessageType::Bitcoin,
CoinProtocol::UTXO { .. } => TrezorMessageType::Bitcoin,
CoinProtocol::QTUM => TrezorMessageType::Bitcoin,
CoinProtocol::ETH { .. } | CoinProtocol::ERC20 { .. } => TrezorMessageType::Ethereum,
_ => return Err(MmError::new(HDExtractPubkeyError::CoinDoesntSupportTrezor)),
Expand Down
20 changes: 15 additions & 5 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4687,11 +4687,21 @@ pub trait IguanaBalanceOps {
async fn iguana_balances(&self) -> BalanceResult<Self::BalanceObject>;
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
/// Information about the UTXO protocol used by a coin.
pub struct UtxoProtocolInfo {
/// A CAIP-2 compliant chain ID. Starts with `b122:`
/// This is used to identify the blockchain when using WalletConnect.
/// https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-4.md
chain_id: String,
}

Comment on lines +4696 to +4704
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should start adding this to coins configs and docs @mariocynicys please open an issue in coins repo and in docs repo. c.c. @cipig @smk762

#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "type", content = "protocol_data")]
pub enum CoinProtocol {
UTXO,
// TODO: Nest this option deep into the innert struct fields when more fields are added to the UTXO protocol info.
UTXO(Option<UtxoProtocolInfo>),
QTUM,
QRC20 {
platform: String,
Expand Down Expand Up @@ -4768,7 +4778,7 @@ impl CoinProtocol {
CoinProtocol::TENDERMINTTOKEN(info) => Some(&info.platform),
#[cfg(not(target_arch = "wasm32"))]
CoinProtocol::LIGHTNING { platform, .. } => Some(platform),
CoinProtocol::UTXO
CoinProtocol::UTXO { .. }
| CoinProtocol::QTUM
| CoinProtocol::ETH { .. }
| CoinProtocol::TRX { .. }
Expand All @@ -4787,7 +4797,7 @@ impl CoinProtocol {
Some(contract_address)
},
CoinProtocol::SLPTOKEN { .. }
| CoinProtocol::UTXO
| CoinProtocol::UTXO { .. }
| CoinProtocol::QTUM
| CoinProtocol::ETH { .. }
| CoinProtocol::TRX { .. }
Expand Down Expand Up @@ -5079,7 +5089,7 @@ pub async fn lp_coininit(ctx: &MmArc, ticker: &str, req: &Json) -> Result<MmCoin
let protocol: CoinProtocol = try_s!(json::from_value(coins_en["protocol"].clone()));

let coin: MmCoinEnum = match &protocol {
CoinProtocol::UTXO => {
CoinProtocol::UTXO { .. } => {
let params = try_s!(UtxoActivationParams::from_legacy_req(req));
try_s!(utxo_standard_coin_with_policy(ctx, ticker, &coins_en, &params, priv_key_policy).await).into()
},
Expand Down Expand Up @@ -5752,7 +5762,7 @@ pub fn address_by_coin_conf_and_pubkey_str(
},
// Todo: implement TRX address generation
CoinProtocol::TRX { .. } => ERR!("TRX address generation is not implemented yet"),
CoinProtocol::UTXO | CoinProtocol::QTUM | CoinProtocol::QRC20 { .. } | CoinProtocol::BCH { .. } => {
CoinProtocol::UTXO { .. } | CoinProtocol::QTUM | CoinProtocol::QRC20 { .. } | CoinProtocol::BCH { .. } => {
utxo::address_by_conf_and_pubkey_str(coin, conf, pubkey, addr_format)
},
CoinProtocol::SLPTOKEN { platform, .. } => {
Expand Down
3 changes: 2 additions & 1 deletion mm2src/coins/rpc_command/init_create_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ impl RpcTask for InitCreateAccountTask {
self.task_state.clone(),
task_handle,
utxo.is_trezor(),
CoinProtocol::UTXO,
// Note that the actual UtxoProtocolInfo isn't needed by trezor XPUB extractor.
CoinProtocol::UTXO(Default::default()),
)
.await?,
)),
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/rpc_command/offline_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ fn extract_prefix_values(

match protocol {
CoinProtocol::ETH { .. } | CoinProtocol::ERC20 { .. } | CoinProtocol::NFT { .. } => Ok(None),
CoinProtocol::UTXO | CoinProtocol::QTUM | CoinProtocol::QRC20 { .. } | CoinProtocol::BCH { .. } => {
CoinProtocol::UTXO { .. } | CoinProtocol::QTUM | CoinProtocol::QRC20 { .. } | CoinProtocol::BCH { .. } => {
let wif_type = coin_conf["wiftype"]
.as_u64()
.ok_or_else(|| OfflineKeysError::MissingPrefixValue {
Expand Down
40 changes: 26 additions & 14 deletions mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ use crate::utxo::{
UtxoRpcMode, UtxoSyncStatus, UtxoSyncStatusLoopHandle, UTXO_DUST_AMOUNT,
};
use crate::{
BlockchainNetwork, CoinTransportMetrics, DerivationMethod, HistorySyncState, IguanaPrivKey, PrivKeyBuildPolicy,
PrivKeyPolicy, PrivKeyPolicyNotAllowed, RpcClientType, SharableRpcTransportEventHandler, UtxoActivationParams,
BlockchainNetwork, CoinProtocol, CoinTransportMetrics, DerivationMethod, HistorySyncState, IguanaPrivKey,
PrivKeyBuildPolicy, PrivKeyPolicy, PrivKeyPolicyNotAllowed, RpcClientType, SharableRpcTransportEventHandler,
UtxoActivationParams,
};
use async_trait::async_trait;
use chain::TxHashAlgo;
Expand Down Expand Up @@ -312,7 +313,7 @@ where

// Construct the PrivKeyPolicy (of WalletConnect type).
let pubkey = PublicKey::from_str(&pubkey).map_err(|e| {
WalletConnectError::ClientError(format!("Received a bad pubkey={} from WalletConnect: {}", pubkey, e))
WalletConnectError::ClientError(format!("Received a bad pubkey={pubkey} from WalletConnect: {e}"))
})?;
let public_key = pubkey.serialize().into();
let public_key_uncompressed = pubkey.serialize_uncompressed().into();
Expand All @@ -339,12 +340,11 @@ where
// corresponds to the public key we have. Otherwise, the wallet (or our address builder) is messed up.
let my_address_serialized = my_address
.display_address()
.map_err(|e| UtxoCoinBuildError::Internal(format!("Failed to serialize address: {}", e)))?;
.map_err(|e| UtxoCoinBuildError::Internal(format!("Failed to serialize address: {e}")))?;
if my_address_serialized != address {
return MmError::err(
WalletConnectError::ClientError(format!(
"Received address={} from WalletConnect doesn't match the expected address={} derived via the public key",
my_address_serialized, address
"Received address={my_address_serialized} from WalletConnect doesn't match the expected address={address} derived via the public key"
))
.into(),
);
Expand Down Expand Up @@ -585,14 +585,26 @@ pub trait UtxoCoinBuilderCommonOps {

/// Returns WcChainId for this coin. Parsed from the coin config.
fn wallet_connect_chain_id(&self) -> UtxoCoinBuildResult<WcChainId> {
let chain_id = self.conf()["chain_id"].as_str().ok_or_else(|| {
WalletConnectError::InvalidChainId(format!(
"coin={} doesn't have chain_id (bip122 standard) set in coin config which is required for WalletConnect",
self.ticker()
))
let protocol: CoinProtocol = json::from_value(self.conf()["protocol"].clone()).map_to_mm(|e| {
UtxoCoinBuildError::ConfError(UtxoConfError::InvalidProtocolData(format!(
"Couldn't parse protocol info: {e}"
)))
})?;
let chain_id = WcChainId::try_from_str(chain_id).map_mm_err()?;
Ok(chain_id)

if let CoinProtocol::UTXO(utxo_info) = protocol {
let utxo_info = utxo_info.ok_or_else(|| {
WalletConnectError::InvalidChainId(format!(
"coin={} doesn't have chain_id (bip122 standard) set in coin config which is required for WalletConnect",
self.ticker()
))
})?;
let chain_id = WcChainId::try_from_str(&utxo_info.chain_id).map_mm_err()?;
Ok(chain_id)
} else {
MmError::err(UtxoCoinBuildError::ConfError(UtxoConfError::InvalidProtocolData(
format!("Expected UTXO protocol, got: {protocol:?}"),
)))
}
}

/// Constructs the full HD derivation path from the coin config and the activation params partial paths.
Expand All @@ -607,7 +619,7 @@ pub trait UtxoCoinBuilderCommonOps {
let full_derivation_path = path_account_to_address
.to_derivation_path(&path_purpose_to_coin)
.map_err(|e| {
UtxoCoinBuildError::InvalidPathToAddress(format!("Failed to construct full derivation path: {}", e))
UtxoCoinBuildError::InvalidPathToAddress(format!("Failed to construct full derivation path: {e}"))
})?;
let full_derivation_path = StandardHDPath::try_from(full_derivation_path).map_err(|e| {
UtxoCoinBuildError::InvalidPathToAddress(format!("Failed to parse full derivation path: {e:?}"))
Expand Down
1 change: 1 addition & 0 deletions mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum UtxoConfError {
InvalidVersionGroupId(String),
InvalidAddressFormat(String),
InvalidDecimals(String),
InvalidProtocolData(String),
}

impl From<Bip32Error> for UtxoConfError {
Expand Down
6 changes: 2 additions & 4 deletions mm2src/coins/utxo/wallet_connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ pub async fn get_walletconnect_address(
} else {
// Otherwise, the response includes a derivation path, which means we didn't find the one that the user was interested in.
MmError::err(WalletConnectError::NoAccountFound(format!(
"No address found for derivation path: {}",
derivation_path
"No address found for derivation path: {derivation_path}"
)))
}
},
Expand Down Expand Up @@ -136,8 +135,7 @@ pub async fn get_pubkey_via_wallatconnect_signature(
let message_hash = sign_message_hash(sign_message_prefix, AUTH_MSG);
let pubkey = Public::recover_compact(&H256::from(message_hash), &signature).map_err(|e| {
WalletConnectError::InternalError(format!(
"Failed to recover public key from walletconnect signature={:?}: {:?}",
signature, e
"Failed to recover public key from walletconnect signature={signature:?}: {e:?}"
))
})?;

Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/z_coin/storage/z_locked_notes/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async fn create_table(conn: Arc<Mutex<AsyncConnection>>) -> Result<(), AsyncConn
impl LockedNotesStorage {
#[cfg(not(any(test, feature = "run-docker-tests")))]
pub(crate) async fn new(ctx: &MmArc, address: String) -> MmResult<Self, LockedNotesStorageError> {
let path = ctx.wallet_dir().join(format!("{}_locked_notes_cache.db", address));
let path = ctx.wallet_dir().join(format!("{address}_locked_notes_cache.db"));
let db = AsyncConnection::open(path)
.await
.map_to_mm(|err| LockedNotesStorageError::SqliteError(err.to_string()))?;
Expand Down
3 changes: 2 additions & 1 deletion mm2src/coins_activation/src/utxo_activation/common_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ where
ctx,
task_handle.clone(),
xpub_extractor_rpc_statuses(),
coins::CoinProtocol::UTXO,
// Note that the actual UtxoProtocolInfo isn't needed by trezor XPUB extractor.
coins::CoinProtocol::UTXO(Default::default()),
)
.mm_err(|_| InitUtxoStandardError::HwError(HwRpcError::NotInitialized))?,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl TryFromCoinProtocol for UtxoStandardProtocolInfo {
Self: Sized,
{
match proto {
CoinProtocol::UTXO => Ok(UtxoStandardProtocolInfo),
CoinProtocol::UTXO { .. } => Ok(UtxoStandardProtocolInfo),
protocol => MmError::err(protocol),
}
}
Expand Down
6 changes: 2 additions & 4 deletions mm2src/kdf_walletconnect/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ const CONNECTION_TIMEOUT_S: f64 = 30.;
/// established pairing by KDF (via [`WalletConnectCtxImpl::new_connection`]).
pub struct NewConnection {
pub url: String,
// TODO: Convert this to a `Topic` instead (after the merger of
// https://github.com/KomodoPlatform/komodo-defi-framework/pull/2499, which pub-uses/exposes `Topic` to other dependent crates)
pub pairing_topic: String,
pub pairing_topic: Topic,
}

/// Broadcast by the lifecycle task so every RPC can cheaply await connectivity.
Expand Down Expand Up @@ -328,7 +326,7 @@ impl WalletConnectCtxImpl {

Ok(NewConnection {
url,
pairing_topic: topic.to_string(),
pairing_topic: topic,
})
}

Expand Down
2 changes: 1 addition & 1 deletion mm2src/mm2_main/src/lp_ordermatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6342,7 +6342,7 @@ fn orderbook_address(
},
// Todo: implement TRX address generation
CoinProtocol::TRX { .. } => MmError::err(OrderbookAddrErr::CoinIsNotSupported(coin.to_owned())),
CoinProtocol::UTXO | CoinProtocol::QTUM | CoinProtocol::QRC20 { .. } | CoinProtocol::BCH { .. } => {
CoinProtocol::UTXO { .. } | CoinProtocol::QTUM | CoinProtocol::QRC20 { .. } | CoinProtocol::BCH { .. } => {
coins::utxo::address_by_conf_and_pubkey_str(coin, conf, pubkey, addr_format)
.map(OrderbookAddress::Transparent)
.map_to_mm(OrderbookAddrErr::AddrFromPubkeyError)
Expand Down
4 changes: 2 additions & 2 deletions mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use kdf_walletconnect::{NewConnection, WalletConnectCtx};
use kdf_walletconnect::{NewConnection, WalletConnectCtx, WcTopic};
use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
use serde::{Deserialize, Serialize};
Expand All @@ -8,7 +8,7 @@ use super::WalletConnectRpcError;
#[derive(Debug, PartialEq, Serialize)]
pub struct CreateConnectionResponse {
pub url: String,
pub pairing_topic: String,
pub pairing_topic: WcTopic,
}

#[derive(Deserialize)]
Expand Down
Loading