-
Notifications
You must be signed in to change notification settings - Fork 98
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 client #2183
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.
Let's try to make unrelated changes in a separate PR next time. It adds more changes to review and makes it harder to identify the actual work.
I haven't reviewed the logical parts yet, but here are some notes from a quick review iteration:
mm2src/kdf_walletconnect/src/lib.rs
Outdated
//! Initially, the implementation was restricted to non-WASM targets, | ||
//! which limited its utility in web-based environments. | ||
//! | ||
//! This module contains the WebSocket client code that has been ported and modified to achieve cross-platform compatibility. |
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.
Can we reference the actual crate here? We might want to review it later to see any improvements they have made.
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.
Also, why did we hard-code/port the entire crate here instead of forking it? Porting the entire source code brings some challanges (such as not being able to track the difference between us and upstream in the future).
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 library is still in its early stages and not very useful at the moment. Important features like the sign API and session management haven’t been implemented yet, so there might be more changes needed when integrating the sign API in the next iteration. So I think it’s reasonable to proceed with porting it..
cc. @onur-ozkan @shamardy
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.
IMO we can still do the same with forking the repository and maintaining it separately. We can publish it to crates.io
as well once it's well documented.
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.
agreed!
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.
Thanks!
First review iteration.
stream.close().await?; | ||
} | ||
|
||
Err(WebsocketClientError::TransportError("Error while closing connection".to_owned()).into()) |
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 that a transport error tho? I think that should be NotConnected
.
p.s. we don't have to error anyways, unless this info is used by the caller.
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'm leaving the fn to return Result for now..
}, | ||
|
||
Err(err) => { | ||
tx.send(Err(ClientError::SerdeError(err.to_string()))).ok(); |
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 we better call this deserialization error
instead of serde
.
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
#[from_stringify("serde_json::Error")] | ||
SerdeError(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.
if this covers also serialization errors, it would be more specific if we make two instances of these (one for serialization and one for deserialization).
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
match data { | ||
Some(result) => { | ||
if let Some(event) = | ||
self.parse_inbound(result.map_err(|err| WebsocketClientError::TransportError(err.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.
nit: would be nicer if we handle the erroring case of the result here and only parse_inbound
the valid msgs.
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
InboundRequest::new(id, data, self.outbound_tx.clone()), | ||
), |
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 can't really follow why we use an unbounded response channel here?
isn't it gonne be just one resposne? it also seems not to be used anywhere later in PublishedMessage
.
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.
note: This code is part of original code from WalletConnect, I also had similar question but I think there might be a good reason to use unbounded_channel
e.g when we don't want to miss a message or have sender blocking
/// Inbound request for receiving a subscription message. | ||
/// | ||
/// Currently, [`Subscription`] is the only request that the Relay sends to | ||
/// the clients. | ||
InboundSubscriptionRequest(InboundRequest<Subscription>), |
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: I would go for calling this just plain InboundRequest
to be general and not mention specific names in this enum. and move the possible request types (currently only this one) into another enum.
} else if self.has_more { | ||
let (req, fut) = create_request(self.request.clone()); |
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: won't this fetch the same request over and over again?
i mean, if we end up with a batch_fut
that has_more
, i expect the next time we call create_request
we specify some different request construction that tells where did the last batch stop.
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.
won't this fetch the same request over and over again
No, it won't and sending same request using same Topics
make sense for streaming messages for some given Topics
.
the rpc includes has_more
in FetchMessages
response body which is later used to update our internal has_more
here
komodo-defi-framework/mm2src/kdf_walletconnect/src/client/fetch.rs
Lines 62 to 64 in 5027a90
self.batch = Some(data.messages.into_iter()); | |
self.has_more = data.has_more; | |
self.batch_fut = None; |
and then we check this condition to make another request with same
Topic
only if batch
and batch_fut
is none.komodo-defi-framework/mm2src/kdf_walletconnect/src/client/fetch.rs
Lines 74 to 77 in 5027a90
} else if self.has_more { | |
let (req, fut) = create_request(self.request.clone()); | |
self.client.request(req); | |
self.batch_fut = Some(fut); |
What I'm saying is that, I believe WalletConnect RPC def uses has_more
internally to stream the request to our client to prevent duplicates.
Does this make sense @mariocynicys
.cargo/config.toml
Outdated
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 it your editor making these changes automatically, or are you making them intentionally?
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.
that's my editor.. sorry 🙁
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 formatting is fine, it's just too much out-of-context change for a feature PR in my opinion
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.
...and the formatting in some Cargo.toml files aren't consistent enough
mm2src/mm2_main/Cargo.toml
Outdated
trezor-udp = [ | ||
"crypto/trezor-udp", | ||
] # use for tests to connect to trezor emulator over udp |
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.
This seems quite bad way of formatting things..
mm2src/crypto/Cargo.toml
Outdated
@@ -34,6 +34,7 @@ mm2_err_handle = { path = "../mm2_err_handle" } | |||
num-traits = "0.2" | |||
parking_lot = { version = "0.12.0", features = ["nightly"] } | |||
primitives = { path = "../mm2_bitcoin/primitives" } | |||
rand = { version = "0.8.0", features = ["std", "small_rng"] } |
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?
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.
had problem with rand crate earlier.. will revert
closing in favor of KomodoPlatform/WalletConnectRust#1 |
Originally, the WalletConnect client implementation only supported non-WASM targets. In this pull request (PR), I have ported the WebSocket client code and modified it to be compatible with both WASM and non-WASM targets.
While some code might change when implementing the session/pairing API in my next PR, this provides a functional WebSocket client implementation for WalletConnect as it stands.