From ba37f7b8d029d3358c7b284f6a2383b9ef9526c9 Mon Sep 17 00:00:00 2001 From: Andrey Shovkoplyas Date: Tue, 5 Mar 2019 15:44:50 +0100 Subject: [PATCH] [#5461] Implement EIP-712 Signed-off-by: Andrey Shovkoplyas --- STATUS_GO_VERSION | 2 +- .../status/ethereum/module/StatusModule.java | 19 ++++++++++++ .../ios/RCTStatus/RCTStatus.m | 13 ++++++++ src/status_im/browser/core.cljs | 4 +-- src/status_im/constants.cljs | 6 ++++ src/status_im/models/wallet.cljs | 2 +- src/status_im/native_module/core.cljs | 3 ++ src/status_im/native_module/impl/module.cljs | 4 +++ .../ui/screens/wallet/send/events.cljs | 30 +++++++++++++------ .../ui/screens/wallet/sign_message/views.cljs | 10 ++++--- 10 files changed, 76 insertions(+), 17 deletions(-) diff --git a/STATUS_GO_VERSION b/STATUS_GO_VERSION index d15acbbe90..b324ca27a0 100644 --- a/STATUS_GO_VERSION +++ b/STATUS_GO_VERSION @@ -1 +1 @@ -0.23.0-beta.7 +0.23.0-beta.8 diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java index 9c779c96e8..b9039053a2 100644 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java @@ -743,6 +743,25 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL StatusThreadPoolExecutor.getInstance().execute(r); } + @ReactMethod + public void signTypedData(final String data, final String password, final Callback callback) { + Log.d(TAG, "signTypedData"); + if (!checkAvailability()) { + callback.invoke(false); + return; + } + + Runnable r = new Runnable() { + @Override + public void run() { + String res = Statusgo.signTypedData(data, password); + callback.invoke(res); + } + }; + + StatusThreadPoolExecutor.getInstance().execute(r); + } + @ReactMethod public void setAdjustResize() { Log.d(TAG, "setAdjustResize"); diff --git a/modules/react-native-status/ios/RCTStatus/RCTStatus.m b/modules/react-native-status/ios/RCTStatus/RCTStatus.m index d773aafa09..eca5af8edc 100644 --- a/modules/react-native-status/ios/RCTStatus/RCTStatus.m +++ b/modules/react-native-status/ios/RCTStatus/RCTStatus.m @@ -318,6 +318,19 @@ RCT_EXPORT_METHOD(signMessage:(NSString *)message callback(@[result]); } +//////////////////////////////////////////////////////////////////// +#pragma mark - SignTypedData +//////////////////////////////////////////////////////////////////// signTypedData +RCT_EXPORT_METHOD(signTypedData:(NSString *)data + password:(NSString *)password + callback:(RCTResponseSenderBlock)callback) { +#if DEBUG + NSLog(@"SignTypedData() method called"); +#endif + NSString *result = StatusgoSignTypedData(data, password); + callback(@[result]); +} + //////////////////////////////////////////////////////////////////// #pragma mark - SignGroupMembership //////////////////////////////////////////////////////////////////// signGroupMembership diff --git a/src/status_im/browser/core.cljs b/src/status_im/browser/core.cljs index cc1a9f42fd..bba2f13223 100644 --- a/src/status_im/browser/core.cljs +++ b/src/status_im/browser/core.cljs @@ -289,8 +289,8 @@ (fx/defn web3-send-async [{:keys [db]} {:keys [method] :as payload} message-id] - (if (or (= method constants/web3-send-transaction) - (= method constants/web3-personal-sign)) + (if (or (= constants/web3-send-transaction method) + (constants/web3-sign-message? method)) {:db (update-in db [:wallet :transactions-queue] conj {:message-id message-id :payload payload}) ;;TODO(yenda): refactor check-dapps-transactions-queue to remove this dispatch :dispatch [:check-dapps-transactions-queue]} diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 6739b5ad72..986a60baca 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -207,6 +207,9 @@ (def ^:const web3-send-transaction "eth_sendTransaction") (def ^:const web3-personal-sign "personal_sign") +(def ^:const web3-sign-typed-data "eth_signTypedData") +(def ^:const web3-sign-typed-data-v3 "eth_signTypedData_v3") + (def ^:const web3-get-logs "eth_getLogs") (def ^:const web3-transaction-receipt "eth_getTransactionReceipt") (def ^:const web3-new-filter "eth_newFilter") @@ -225,6 +228,9 @@ (def ^:const web3-shh-get-filter-changes "shh_getFilterChanges") (def ^:const web3-shh-get-messages "shh_getMessages") +(defn web3-sign-message? [method] + (#{web3-sign-typed-data web3-sign-typed-data-v3 web3-personal-sign} method)) + (def ^:const status-create-address "status_createaddress") (def ^:const event-transfer-hash diff --git a/src/status_im/models/wallet.cljs b/src/status_im/models/wallet.cljs index aecec8bbe5..eaae310f47 100644 --- a/src/status_im/models/wallet.cljs +++ b/src/status_im/models/wallet.cljs @@ -129,7 +129,7 @@ :webview webview} :dispatch [:navigate-back]} - (= method constants/web3-personal-sign) + (constants/web3-sign-message? method) (assoc :dispatch [:navigate-back]) (= method constants/web3-send-transaction) diff --git a/src/status_im/native_module/core.cljs b/src/status_im/native_module/core.cljs index 1562c7cfc7..1a609d10c4 100644 --- a/src/status_im/native_module/core.cljs +++ b/src/status_im/native_module/core.cljs @@ -49,6 +49,9 @@ (defn sign-message [rpcParams callback] (native-module/sign-message rpcParams callback)) +(defn sign-typed-data [data password callback] + (native-module/sign-typed-data data password callback)) + (defn send-transaction [rpcParams password callback] (native-module/send-transaction rpcParams password callback)) diff --git a/src/status_im/native_module/impl/module.cljs b/src/status_im/native_module/impl/module.cljs index 1237a1168e..8d6df732f2 100644 --- a/src/status_im/native_module/impl/module.cljs +++ b/src/status_im/native_module/impl/module.cljs @@ -104,6 +104,10 @@ (when (and @node-started status) (.hashTransaction status rpcParams callback))) +(defn sign-typed-data [data password callback] + (when (and @node-started status) + (.signTypedData status data password callback))) + (defn send-transaction [rpcParams password callback] (when (and @node-started status) (.sendTransaction status rpcParams password callback))) diff --git a/src/status_im/ui/screens/wallet/send/events.cljs b/src/status_im/ui/screens/wallet/send/events.cljs index a79fcb74e6..968fe2a9a8 100644 --- a/src/status_im/ui/screens/wallet/send/events.cljs +++ b/src/status_im/ui/screens/wallet/send/events.cljs @@ -46,6 +46,11 @@ (status/sign-message (types/clj->json params) on-completed))) +(re-frame/reg-fx + ::sign-typed-data + (fn [{:keys [data on-completed password]}] + (status/sign-typed-data data (security/safe-unmask-data password) on-completed))) + (re-frame/reg-fx :wallet/show-transaction-error (fn [message] @@ -75,12 +80,17 @@ ;; SIGN MESSAGE (handlers/register-handler-fx :wallet/sign-message - (fn [_ [_ screen-params]] + (fn [_ [_ typed? screen-params]] (let [{:keys [data from password]} screen-params] - {::sign-message {:params {:data data - :password (security/safe-unmask-data password) - :account from} - :on-completed #(re-frame/dispatch [::sign-message-completed screen-params (types/json->clj %)])}}))) + (if typed? + {::sign-typed-data {:data data + :password password + :account from + :on-completed #(re-frame/dispatch [::sign-message-completed screen-params (types/json->clj %)])}} + {::sign-message {:params {:data data + :password (security/safe-unmask-data password) + :account from} + :on-completed #(re-frame/dispatch [::sign-message-completed screen-params (types/json->clj %)])}})))) ;; SEND TRANSACTION CALLBACK (handlers/register-handler-fx @@ -95,7 +105,7 @@ (merge {:db (cond-> (assoc-in db' [:wallet :send-transaction] {}) - (not= method constants/web3-personal-sign) + (not (constants/web3-sign-message? method)) (assoc-in [:wallet :transactions result] (models.wallet/prepare-unconfirmed-transaction db now result)))} @@ -157,13 +167,15 @@ (models.wallet/open-modal-wallet-for-transaction db' transaction (first params))) ;;SIGN MESSAGE - (= method constants/web3-personal-sign) - (let [[address data] (models.wallet/normalize-sign-message-params params)] + (constants/web3-sign-message? method) + (let [typed? (not= constants/web3-personal-sign method) + [address data] (models.wallet/normalize-sign-message-params params)] (if (and address data) (let [screen-params {:id (str (or id message-id)) :from address :data data - :decoded-data (transport.utils/to-utf8 data) + :typed? typed? + :decoded-data (if typed? (types/json->clj data) (transport.utils/to-utf8 data)) :on-result [:wallet.dapp/transaction-on-result message-id] :on-error [:wallet.dapp/transaction-on-error message-id] :method method}] diff --git a/src/status_im/ui/screens/wallet/sign_message/views.cljs b/src/status_im/ui/screens/wallet/sign_message/views.cljs index 8efa5dce39..f9d485faeb 100644 --- a/src/status_im/ui/screens/wallet/sign_message/views.cljs +++ b/src/status_im/ui/screens/wallet/sign_message/views.cljs @@ -82,7 +82,7 @@ ;; SIGN MESSAGE FROM DAPP (defview sign-message-modal [] (letsubs [value-atom (reagent/atom nil) - {:keys [decoded-data in-progress?] :as screen-params} [:get-screen-params :wallet-sign-message-modal] + {:keys [decoded-data in-progress? typed?] :as screen-params} [:get-screen-params :wallet-sign-message-modal] network-status [:network-status]] [wallet.components/simple-screen {:status-bar-type :modal-wallet} [toolbar true (i18n/label :t/sign-message)] @@ -97,12 +97,14 @@ {:disabled? true :input-options {:multiline true :height 100} - :amount-text decoded-data} + :amount-text (if typed? + (str "Domain\n" (:domain decoded-data) "\nMessage\n" (:message decoded-data)) + decoded-data)} nil]]]] [enter-password-buttons value-atom false #(re-frame/dispatch [:wallet/discard-transaction-navigate-back]) - #(re-frame/dispatch [:wallet/sign-message (merge screen-params @value-atom)]) + #(re-frame/dispatch [:wallet/sign-message typed? (merge screen-params @value-atom)]) :t/transactions-sign] [password-input-panel value-atom :t/signing-message-phrase-description false] (when in-progress? - [react/view styles/processing-view])]])) + [react/view styles/processing-view])]])) \ No newline at end of file