-
Notifications
You must be signed in to change notification settings - Fork 94
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
[r2r] MetaMask PoC #1551
[r2r] MetaMask PoC #1551
Conversation
* Add MetaMask initialization RPCs
* Add `EthPrivKeyPolicy`
* Add `MetamaskTransport` * Rename `Web3Transport` to `HttpTransport` * Add `MetamaskSession` to prevent concurrent requests
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 for the PR! Few questions and minor proposals for the first iteration.
_ => MmError::err(DispatcherError::NoSuchMethod), | ||
wasm_only_methods => match wasm_only_methods { | ||
"init_metamask::cancel" => handle_mmrpc(ctx, request, cancel_init_metamask).await, | ||
"init_metamask::init" => handle_mmrpc(ctx, request, init_metamask).await, |
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 I understand correctly that GUI will first have to invoke init_metamask::init
before attempting to initialize e.g. ETH in Metamask mode?
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, right
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.
Ok, after thinking for some time, I think it's fine and even good. I hope it won't cause confusion or tricky state tracking on GUI side - will clarify it with Flutter team later 🙂
* Compile `EthRpcMode::Metamask` in WASM only * Add `rpc_mode: EthRpcMode` to `EthActivationV2Request` * Update wasm-timer
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 for the great work! I have just one note for the future.
@@ -0,0 +1,168 @@ | |||
//! This module is inspired by https://github.com/tomusdrw/rust-web3/blob/master/src/transports/eip_1193.rs |
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.
For the next iteration: should we update rust-web3
dependency instead? We use a quite outdated fork now.
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 can be difficult due to the fact that Eip1193 transport is local only, so we'll need to make a workaround anyway.
Currently, EthProvider
is Send because it's wrapped into the event-driven pattern
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 can be difficult due to the fact that Eip1193 transport is local only, so we'll need to make a workaround anyway.
@sergeyboyko0791 Could you please try to find a work around next sprint? It might be great to not reinvent the wheel, if work around itself is not too hard, 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.
Awesome feature implementation 🔥
My first review iteration:
mm2src/coins/eth.rs
Outdated
impl fmt::Debug for EthPrivKeyPolicy { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
match self { | ||
EthPrivKeyPolicy::KeyPair(_) => write!(f, "KeyPair"), | ||
#[cfg(target_arch = "wasm32")] | ||
EthPrivKeyPolicy::Metamask(_) => write!(f, "Metamask"), | ||
} | ||
} | ||
} |
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 isn't used. Should we keep it implemented?
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.
Oh, looks like it used to be used before. Will remove it, thanks
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
mm2src/coins/eth.rs
Outdated
pub fn key_pair(&self) -> Option<&KeyPair> { | ||
match self { | ||
EthPrivKeyPolicy::KeyPair(key_pair) => Some(key_pair), | ||
#[cfg(target_arch = "wasm32")] | ||
EthPrivKeyPolicy::Metamask(_) => None, | ||
} | ||
} | ||
|
||
pub fn key_pair_or_err(&self) -> MmResult<&KeyPair, PrivKeyPolicyNotAllowed> { | ||
self.key_pair() | ||
.or_mm_err(|| PrivKeyPolicyNotAllowed::HardwareWalletNotSupported) | ||
} |
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.
fn key_pair
itself isn't used anywhere. What do you think returning MmResult
directly in key_pair
fn and remove key_pair_or_err
?
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 repeated the same methods from lp_coins::PrivKeyPolicy
, so how about removing EthPrivKeyPolicy::key_pair
method, but leaving EthPrivKeyPolicy::key_pair_or_err
as it is? If renaming it to key_pair
, it's also worth to rename PrivKeyPolicy::key_pair_or_err
. But this will result in changes to files not related to this task.
What do you think?
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.
how about removing
EthPrivKeyPolicy::key_pair
method, but leavingEthPrivKeyPolicy::key_pair_or_err
as it is?
I think it's also fine.
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
mm2src/coins/eth/v2_activation.rs
Outdated
/// The function can be used as a default deserialization constructor: | ||
/// `#[serde(default = "EthPrivKeyActivationPolicy::context_priv_key")]` |
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 there a specific reason why we didn't implement Default
trait for this use case?
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, there is no reason. I think I also can implement Default for lp_coins::PrivKeyActivationPolicy
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
use web3::helpers::build_request; | ||
use web3::{RequestId, Transport}; | ||
|
||
const REQUEST_ID: RequestId = 0; |
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 is only related with fn prepare
, it can be defined there I think. When we see values defined on top-level, it gives an idea that they are used in different spots.
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
} | ||
|
||
#[cfg(test)] | ||
#[inline] |
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.
Inlining doesn't help much but increases compilation for tests
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.
Removed it
@@ -44,6 +46,10 @@ impl From<EthActivationV2Error> for EnablePlatformCoinWithTokensError { | |||
EthActivationV2Error::PrivKeyPolicyNotAllowed(e) => { | |||
EnablePlatformCoinWithTokensError::PrivKeyPolicyNotAllowed(e) | |||
}, | |||
#[cfg(target_arch = "wasm32")] | |||
EthActivationV2Error::MetamaskCtxNotInitialized => EnablePlatformCoinWithTokensError::PreparationRequired( | |||
"MetaMask context is not initialized. Consider using 'task::init_metamask::init' RPC".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.
What about using RPC method name here?
"MetaMask context is not initialized. Consider using 'task::init_metamask::init' RPC".to_string(), | |
"MetaMask context is not initialized. Consider using 'init_metamask::init' RPC".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.
Its actual name is task::init_metamask::init
:
https://github.com/KomodoPlatform/atomicDEX-API/blob/bf3fa88285d1293af54a05ec93318fcc598da9ca/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs#L130-L133
https://github.com/KomodoPlatform/atomicDEX-API/blob/bf3fa88285d1293af54a05ec93318fcc598da9ca/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs#L250-L252
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.
Oops. I didn't saw it :)
Can it be task::metamask::init/cancel/status
or task::metamask_activation::init/cancel/status
?
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 definitely makes sense! My initial though was to follow this naming scheme:
task::<Purpose of the task/what it does>::<An action on the task>
, so we could add task::update_metamask::<ACTION>
or task::check_metamask::<ACTION>
RPCs later.
How about task::connect_metamask::<ACTION>
?
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.
How about
task::connect_metamask::<ACTION>
?
Seems completely fine :)
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, I decided not to rename related structures like InitMetamaskRequest
and functions like CryptoCtx::init_metamask_ctx
. Is it fine? I'm afraid there will be many changes.
@ozkanonur PR is ready for the next review :) |
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.
Great progress on such an important feature 🔥
Only 2 non-blockers :)
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.
Re-approving
priv_key_policy: "Metamask"
viaenable_eth_with_tokens
.TODOs: