-
Notifications
You must be signed in to change notification settings - Fork 97
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
session.relay = settle.relay; | ||
session.expiry = settle.expiry; | ||
|
||
if let Some(value) = settle.session_properties { |
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.
any reason why not let settle.session_properties
be of type Option<SessionProperties>
instead of Option<Value>
?
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.
session_properties
field varies depending on the wallet and is currently used primarily by certain wallets like Keplr
. Its fields can differ across wallets, as it isn’t standardized.
We can extend this using any enum once more wallets are discovered. For now, only Keplr
sends this field during session initialization afaik.
pub session_properties: Option<SessionProperties>, |
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 you mean we want to be able to discard this field if we were not able to deserialize it?
i think then the serde_json::from_str::<SessionProperties>(&value.to_string())?
should be optional, i.e. we shouldn't fail (?
) the whole function if we fail deserializing the arbitrary value.
p.s. we can also use serde_json::from_value
instead of from_str
and ditch .to_string()
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.
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.
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.
any reason why not let
settle.session_properties
be of typeOption<SessionProperties>
instead ofOption<Value>
?
settle.session_properties
is generic I mean it can be any arbitrary data depending on the wallet of course.
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.
so,
- if
session_properties
isn't sent, it's fine since it's optional, - if
session_properties
is sent along in the request, we MUST succeed in parsing it (that means we must have an enumration of all the possible shapes it could be)- if we fail to de-serialize
session_properties
we will fail the request (the MUST part).
- if we fail to de-serialize
why do we need it as Option<Value>
(instead of Option<SessionProperties>
) if we will fail the request if we fail to deserialize it?
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.
not all wallet will send this payload e.g metamask doesn't send but Kelpr does and maybe TrustWallet
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.
if it's not sent we will deserialize it as None
(because session_properties: Option<SessionProps>
) so it's fine and exactly the same as using Option<Value>
. the only diff is we let serde deser the value instead of we desering it ourselves.
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.
another thing, WalletConnect lib shouldn't handle this data since it can't know what type it is so that's why I delegate the data deserialization to the lib user, which I assume is the right way.
LIBRARY: doesn't have any idea what data it is, so session_properties: Option<Value>
USER: have an idea of what the data type is, so Option<SessionProps>
// Delete other sessions with same controller | ||
// TODO: we might not want to do this! |
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.
Q to get more context: why do we delete sessions with the same controller?
and what does the controller mean/does?
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.
Let's say there's already a session with Metamask wallet, any new connection with Metamask will override the existing connection.
So, I'm unsure if we should do this!
Some(value) => Some(serde_json::from_value(value)?), | ||
None => None, | ||
}; | ||
let (topic, url) = self.pairing.create(self.metadata.clone(), None)?; |
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 then we should clean up these old pairings.
/// Information about the controlling party (typically a wallet). | ||
pub controller: Controller, | ||
/// Information about the proposing party (typically a dApp). | ||
pub proposer: Proposer, |
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 mean the other one is always Default::default()
so an enum makes sense here then we can store only one of them.
session.relay = settle.relay; | ||
session.expiry = settle.expiry; | ||
|
||
if let Some(value) = settle.session_properties { |
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 you mean we want to be able to discard this field if we were not able to deserialize it?
i think then the serde_json::from_str::<SessionProperties>(&value.to_string())?
should be optional, i.e. we shouldn't fail (?
) the whole function if we fail deserializing the arbitrary value.
p.s. we can also use serde_json::from_value
instead of from_str
and ditch .to_string()
let topic = session.topic.clone(); | ||
let pairing_topic = session.pairing_topic.clone(); | ||
debug!("[{topic}] Session found! activating"); | ||
self.session_manager.add_session(session); |
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.
why don't we add their pairings?
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.
no use for storing pairings as they're only needed to activate a session and then we'll move to using session for all communication. albeit I still consider extending pairing storage just like session storage but there's not any use for it right now.
{ | ||
ctx.pairing.activate(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.
the extra scope not needed.
also this always returns error (check KomodoPlatform/WalletConnectRust#3 (comment))
let irn_metadata = param.irn_metadata(); | ||
let ttl = irn_metadata.ttl; |
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 can use a timed/expirable map for this case. we do that for electrum and eth also i think. this is to avoid network-induced memory leaks.
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 mainly went over some of old comments and resolved the ones which i can see have been updated (could use a helping hand in the remaining ones by pointing where the updates are).
my estimation right now is i would need one more all-over iteration for approval (+ old comments), but i don't wanna promise since break my promises :D
Thanks for that huge work!
session.relay = settle.relay; | ||
session.expiry = settle.expiry; | ||
|
||
if let Some(value) = settle.session_properties { |
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.
so,
- if
session_properties
isn't sent, it's fine since it's optional, - if
session_properties
is sent along in the request, we MUST succeed in parsing it (that means we must have an enumration of all the possible shapes it could be)- if we fail to de-serialize
session_properties
we will fail the request (the MUST part).
- if we fail to de-serialize
why do we need it as Option<Value>
(instead of Option<SessionProperties>
) if we will fail the request if we fail to deserialize it?
|
||
self.validate_chain_id(&session, chain_id)?; | ||
|
||
// TODO: uncomment when WalletConnect wallets start listening to chainChanged event |
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.
So nothing happens(I mean wallets don't listen to this event) if we send such request
so what about just sending it for now and when wallets listen to it later we get this feat for free
Two reasons I didn't want to, this will add extra latency and corresponding wallet will return error as they don't recognize such session request |
#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": "WalletConnect",
in activation params).Note: To add more
eip155
chains, modify the chains array like this:["eip155:1", "eip155:250"]