-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(walletconnect): walletconnect integration #2223
base: dev
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done soon :)
there is one pending request in the previous review iter.
mm2src/kdf_walletconnect/Cargo.toml
Outdated
[target.'cfg(target_arch = "wasm32")'.dependencies] | ||
js-sys = { version = "0.3.27" } | ||
mm2_db = { path = "../mm2_db" } | ||
mm2_test_helpers = { path = "../mm2_test_helpers" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shouldn't need this crate here? no?
mm2src/kdf_walletconnect/src/lib.rs
Outdated
@@ -358,10 +359,11 @@ impl WalletConnectCtxImpl { | |||
.await?; | |||
|
|||
let (tx, rx) = oneshot::channel(); | |||
// insert request to map with a reasonable expiration time of 30 minutes | |||
self.pending_requests | |||
.lock() | |||
.expect("pending request lock shouldn't fail!") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we can just unwrap here. no need for justification for mutex unwraps.
mm2src/kdf_walletconnect/src/lib.rs
Outdated
@@ -358,10 +359,11 @@ impl WalletConnectCtxImpl { | |||
.await?; | |||
|
|||
let (tx, rx) = oneshot::channel(); | |||
// insert request to map with a reasonable expiration time of 30 minutes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ummm... isn't 30 mins veeery long?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a user, i wouldn't accept any WC msg if it came so late. that's sus.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WalletConnect doesn't limit timeout it all depends on the timeout we want to set for each request.
I agree 30minsis a very long expiration time.
reduced to 5 mins
let _nonce_lock = address_lock.lock().await; | ||
let pay_for_gas_option = if let Some(ref pay_for_gas) = args.pay_for_gas { | ||
pay_for_gas.clone().try_into()? | ||
} else { | ||
// use legacy gas_price() if not set | ||
info!(target: "sign-and-send", "get_gas_price…"); | ||
let gas_price = coin.get_gas_price().await?; | ||
PayForGasOption::Legacy(LegacyGasPrice { gas_price }) | ||
}; | ||
let (nonce, _) = coin | ||
.clone() | ||
.get_addr_nonce(my_address) | ||
.compat() | ||
.await | ||
.map_to_mm(RawTransactionError::InvalidParam)?; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am curious about if we can handle nonces in a lockless way (like how it's done in TendermintCoin::seq_safe_send_raw_tx_bytes
for tendermint sequences), so we can perform concurrent txs on for ETH.
Perhaps we should create a tracking issue for this topic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should create a tracking issue for this topic?
wait_rpc_timeout_ms: u64, | ||
wait_rpc_timeout_s: u64, | ||
check_every: f64, | ||
) -> Web3RpcResult<Option<SignedEthTx>> { | ||
let wait_until = wait_until_ms(wait_rpc_timeout_ms); | ||
while now_ms() < wait_until { | ||
let wait_until = wait_until_sec(wait_rpc_timeout_s); | ||
while now_sec() < wait_until { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any motivation for this change? Milliseconds can be more useful for such logic flows as it can be configurable more precisely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mm2src/coins/eth/wallet_connect.rs
Outdated
let to_addr = match self.action { | ||
Action::Create => None, | ||
Action::Call(addr) => Some(addr), | ||
}; | ||
if let Some(to) = to_addr { | ||
tx_json | ||
.as_object_mut() | ||
.unwrap() | ||
.insert("to".to_string(), json!(format!("0x{}", hex::encode(to.as_bytes())))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be simpler with if let Action::Call(addr) = self.action
.
mm2src/coins/eth/wallet_connect.rs
Outdated
let mut tx_json = json!({ | ||
"nonce": u256_to_hex(self.nonce), | ||
"from": format!("{:x}", self.my_address), | ||
"gas": u256_to_hex(self.gas), | ||
"value": u256_to_hex(self.value), | ||
"data": format!("0x{}", hex::encode(self.data)) | ||
}); | ||
|
||
if let Some(gas_price) = self.gas_price { | ||
tx_json | ||
.as_object_mut() | ||
.unwrap() | ||
.insert("gasPrice".to_string(), json!(u256_to_hex(gas_price))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use serde_json::Map
to avoid as_object_mut().unwrap()
calls for easier mutation and convert it to serde_json::Value
once you are done with mutating it.
mm2src/coins/eth/wallet_connect.rs
Outdated
let chain_id = WcChainId::new_eip155(self.chain_id.to_string()); | ||
let session_topic = self.session_topic()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move session_topic
above as it's fallible but the chain_id
is not.
.send_session_request_and_wait(session_topic, &chain_id, WcRequestMethods::EthSignTransaction, tx_json) | ||
.await?; | ||
// First 4 bytes from WalletConnect represents Protoc info | ||
hex::decode(&tx_hex[4..])? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be more safe to check length of tx_hex
first.
wc.validate_update_active_chain_id(session_topic, &chain_id).await?; | ||
|
||
let (account_str, _) = wc.get_account_and_properties_for_chain_id(session_topic, &chain_id)?; | ||
let message = "Authenticate with Komodefi"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to show-up on the external wallet screen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs approval from various people outside our team whether we want to present ourselves as Komodefi
or we should prefer some other name.
cc @ca333
471bac3
to
cbf92c7
Compare
Current code state fails to build/run https://github.com/KomodoPlatform/komodo-defi-framework/actions/runs/13696493437/job/38300021140?pr=2223#step:10:1222 (same error seen locally with Commit 167734b (prior to merging in |
Would it be ok to use actual chain/network name as shown in coins file instead? |
No, just the chain_id https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces |
Unfortunately I'm still having some trouble with this. Notes below: Test Workflow
If using the "pairing topic" (i.e. General notes:
|
Komodefi WalletConnect Test Flow1. External Wallet Connection Test FlowI will be using
{
"method": "wc_get_session",
"userpass": "{{ _.userpass }}",
"mmrpc": "2.0",
"params": {
"with_pairing_topic": true,
"topic": "efe5d00ff97750d40e96f0e794cc10106245da8b98091af69d2d42faa94efcd5"
}
}
2. Coin Activation Test Flow(Needs 1 to be completed)
}
|
Thanks. I'm still having some issues with Trust Wallet failing to scan more often than not, so its been a bit difficult to progress with testing, tho I've added the docs I can so far, Can you please confirm Code at https://github.com/KomodoPlatform/komodo-defi-framework/blob/wc-integration/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs#L45 implies it as input, but when using it I'm getting error returned. E.g Session is {
"topic": "feeabbad7ac1f1ba720d4441c299eab2b239f0deefb050fe50dbc7a350d55f75",
"metadata": {
...
},
"pairing_topic": "ad604cd186f5dc9498343fbd763f6d6963ea511de0e5d557a33a8e3790d6d4d5",
"namespaces": {
...
},
"expiry": 1741952829
} Using topic When request is sent, logs show
but the request continues to wait. After timeout for If using the pairing topic with
the response is error: {
"mmrpc": "2.0",
"error": "Internal Error: topic sym_key not found: 31ad8ac1312e01ff7ff656ed5507eb9fd6f2f435668fd86331e00b33627bfc14",
"error_path": "sessions.lib",
"error_trace": "sessions:69] lib:281]",
"error_type": "SessionRequestError",
"error_data": "Internal Error: topic sym_key not found: 31ad8ac1312e01ff7ff656ed5507eb9fd6f2f435668fd86331e00b33627bfc14",
"id": null
} Incidentally, when set to |
I'm also facing timeouts sometimes when attempting to activate ETH. In logs I see:
This instance above was on a topic I attempted to delete, which might explain it a little. A fresh connection, attempting ETH activation post QR scan returned
Which blocks me from any further tests :( When attempting to initiate another connection at this point, Trust wallet will scan the QR code, but then does nothing (no modal to confirm etc). Seems I need to uninstall, reinstall and use a fresh seed to wake it up again. |
No, |
Both these methods are working as expected using https://react-wallet.walletconnect.com/ (instead of Trust Wallet android app), and I am able to activate ETH/AVAX/MATIC (with wc confirmation). Unfortunately unable to withdraw, details of browser console error has been shared with @borngraced |
#1543
This PR introduces the integration of WalletConnect into the Komodo DeFi Framework (KDF), enabling secure wallet connections for Cosmos and EVM-based chains. KDF acts as the DApp(in this PR), allowing users to initiate and manage transactions securely with external wallets e.g via Metamask.
Key changes include:
Tendermint
andEVM
.Tendermint
andEVM
https://specs.walletconnect.com/2.0/specs/clients/sign/
https://specs.walletconnect.com/2.0/specs/clients/core/pairing/
https://specs.walletconnect.com/2.0/specs/clients/core/crypto/
https://specs.walletconnect.com/2.0/specs/servers/relay/
https://docs.reown.com/advanced/multichain/rpc-reference/ethereum-rpc
Additional improvements include cleanup of unused dependencies, minor code refinements, and WASM compatibility
Updated deps:
Added deps:
Removed deps:
How to test using EVM coin e.g
ETH
(Native && WASM)cargo run
)ETH
coin (set"priv_key_policy": "wallet_connect": { "session_topic": your_session_topic" }
in activation params).Note: To add more
eip155
chains, modify the chains array like this:["eip155:1", "eip155:250"]
New RPC Methods
New connection
method: wc_new_connection
Get/Retrieve Walletconnect session(s)
method: wc_get_session | wc_get_sessions
Ping Walletconnect session
method: wc_ping_session
Delete Walletconnect session
method: wc_delete_session
Active ETH/ERC
method: enable_eth_with_tokens
Active Tendermint/Cosmos
method: enable_tendermint_with_assets
cc @smk762