From 53d5ac4ea2af97f3814bf79e4acc34e046887626 Mon Sep 17 00:00:00 2001 From: Lungu Cristian Date: Fri, 29 Nov 2024 09:18:12 +0200 Subject: [PATCH] Using Keycard with the new Endpoints for Send/Bridge (#21705) * fix: routes component annoying warning * feat: replaced keycard sign with sign-hashes * feat: using the keycard to sign transactions * fix: removed unused and weird imports * chore: removed debug logs * chore: linting * fix: removed clearing data on send error --- src/keycard/keycard.cljs | 26 ++++--- src/status_im/common/log.cljs | 4 +- src/status_im/common/signals/events.cljs | 6 -- src/status_im/contexts/keycard/effects.cljs | 19 +++++- .../contexts/keycard/sign/events.cljs | 31 +++------ src/status_im/contexts/keycard/utils.cljs | 6 +- .../contexts/wallet/send/events.cljs | 49 +++++++++----- .../contexts/wallet/send/routes/view.cljs | 67 ++++++++++--------- .../send/transaction_confirmation/view.cljs | 3 +- 9 files changed, 119 insertions(+), 92 deletions(-) diff --git a/src/keycard/keycard.cljs b/src/keycard/keycard.cljs index 9820200093..915974050a 100644 --- a/src/keycard/keycard.cljs +++ b/src/keycard/keycard.cljs @@ -2,7 +2,9 @@ (:require ["react-native" :as rn] ["react-native-status-keycard" :default status-keycard] + [oops.core :as oops] [react-native.platform :as platform] + [schema.core :as schema] [taoensso.timbre :as log])) (defonce event-emitter @@ -254,17 +256,19 @@ (catch on-failure)))) (defn sign - [{pin :pin path :path card-hash :hash on-success :on-success on-failure :on-failure}] - (when (and pin card-hash) - (if path - (.. status-keycard - (signWithPath pin path card-hash) - (then on-success) - (catch on-failure)) - (.. status-keycard - (sign pin card-hash) - (then on-success) - (catch on-failure))))) + [{:keys [pin path hash-data]}] + (if path + (oops/ocall status-keycard "signWithPath" pin path hash-data) + (oops/ocall status-keycard "sign" pin hash-data))) + +(schema/=> sign + [:=> + [:cat + [:map + [:pin :string] + [:hash-data :string] + [:path {:optional true} [:maybe :string]]]] + :any]) (defn sign-typed-data [{card-hash :hash on-success :on-success on-failure :on-failure}] diff --git a/src/status_im/common/log.cljs b/src/status_im/common/log.cljs index 56609abc78..27b753bcfa 100644 --- a/src/status_im/common/log.cljs +++ b/src/status_im/common/log.cljs @@ -1,6 +1,6 @@ (ns status-im.common.log (:require - [clojure.pprint :as promesa] + [clojure.pprint :as pprint] [clojure.string :as string] [native-module.core :as native-module] [re-frame.core :as re-frame] @@ -46,7 +46,7 @@ (update data :vargs (partial mapv - #(if (string? %) % (with-out-str (promesa/pprint %))))))]}) + #(if (string? %) % (with-out-str (pprint/pprint %))))))]}) (native-module/init-status-go-logging logging-params))))) (re-frame/reg-fx diff --git a/src/status_im/common/signals/events.cljs b/src/status_im/common/signals/events.cljs index 790f7d12c9..c1090dd470 100644 --- a/src/status_im/common/signals/events.cljs +++ b/src/status_im/common/signals/events.cljs @@ -36,12 +36,6 @@ "wallet" {:fx [[:dispatch [:wallet/signal-received event-js]]]} - "wallet.sign.transactions" - {:fx [[:dispatch - [:standard-auth/authorize-with-keycard - {:on-complete #(rf/dispatch [:keycard/sign-hash % - (first (transforms/js->clj event-js))])}]]]} - "wallet.suggested.routes" {:fx [[:dispatch [:wallet/handle-suggested-routes (transforms/js->clj event-js)]]]} diff --git a/src/status_im/contexts/keycard/effects.cljs b/src/status_im/contexts/keycard/effects.cljs index 0051c60dd3..6c1d41f767 100644 --- a/src/status_im/contexts/keycard/effects.cljs +++ b/src/status_im/contexts/keycard/effects.cljs @@ -1,11 +1,13 @@ (ns status-im.contexts.keycard.effects (:require [keycard.keycard :as keycard] [native-module.core :as native-module] + [promesa.core :as promesa] [react-native.async-storage :as async-storage] [react-native.platform :as platform] status-im.contexts.keycard.nfc.effects [status-im.contexts.keycard.utils :as keycard.utils] [status-im.contexts.profile.config :as profile.config] + [utils.hex :as hex] [utils.re-frame :as rf])) (defonce ^:private active-listeners (atom [])) @@ -50,7 +52,22 @@ (rf/reg-fx :effects.keycard/sign (fn [args] - (keycard/sign (keycard.utils/wrap-handlers args)))) + (-> (keycard/sign args) + (promesa/then (keycard.utils/get-on-success args)) + (promesa/catch (keycard.utils/get-on-failure args))))) + +(rf/reg-fx :effects.keycard/sign-hashes + (fn [{:keys [hashes pin path on-success] :as args}] + (-> (promesa/all + (for [hash-data hashes] + (-> (keycard/sign {:pin pin + :path path + :hash-data (hex/normalize-hex hash-data)}) + (promesa/then (fn [signature] + {:signature signature + :message hash-data}))))) + (promesa/then on-success) + (promesa/catch (keycard.utils/get-on-failure args))))) (rf/reg-fx :keycard/init-card (fn [args] diff --git a/src/status_im/contexts/keycard/sign/events.cljs b/src/status_im/contexts/keycard/sign/events.cljs index 4e4529e0ac..4c9d9b2bb9 100644 --- a/src/status_im/contexts/keycard/sign/events.cljs +++ b/src/status_im/contexts/keycard/sign/events.cljs @@ -2,33 +2,24 @@ (:require [utils.address] [utils.re-frame :as rf])) -(defn get-signature-map - [tx-hash signature] - {tx-hash {:r (subs signature 0 64) - :s (subs signature 64 128) - :v (subs signature 128 130)}}) - -(rf/reg-event-fx :keycard/sign +(rf/reg-event-fx :keycard/sign-hashes (fn [_ [data]] - {:effects.keycard/sign data})) + {:effects.keycard/sign-hashes data})) -(rf/reg-event-fx :keycard/sign-hash - (fn [{:keys [db]} [pin-text tx-hash]] - (let [current-address (get-in db [:wallet :current-viewing-account-address]) - path (get-in db [:wallet :accounts current-address :path]) - key-uid (get-in db [:profile/profile :key-uid])] +(rf/reg-event-fx :keycard/connect-and-sign-hashes + (fn [{:keys [db]} [{:keys [keycard-pin address hashes on-success on-failure]}]] + (let [{:keys [path key-uid]} (get-in db [:wallet :accounts address])] {:fx [[:dispatch [:keycard/connect {:key-uid key-uid :on-success (fn [] (rf/dispatch - [:keycard/sign - {:pin pin-text + [:keycard/sign-hashes + {:pin keycard-pin :path path - :hash (utils.address/naked-address tx-hash) - :on-success (fn [signature] + :hashes hashes + :on-success (fn [signatures] (rf/dispatch [:keycard/disconnect]) - (rf/dispatch [:wallet/proceed-with-transactions-signatures - (get-signature-map tx-hash signature)])) - :on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]))}]]]}))) + (when on-success (on-success signatures))) + :on-failure on-failure}]))}]]]}))) diff --git a/src/status_im/contexts/keycard/utils.cljs b/src/status_im/contexts/keycard/utils.cljs index 6742650e91..78cc099a58 100644 --- a/src/status_im/contexts/keycard/utils.cljs +++ b/src/status_im/contexts/keycard/utils.cljs @@ -57,9 +57,13 @@ data (update data :key-uid address/normalized-hex))) +(defn format-success-data + [data] + (normalize-key-uid (transforms/js->clj data))) + (defn get-on-success [{:keys [on-success]}] - #(when on-success (on-success (normalize-key-uid (transforms/js->clj %))))) + #(when on-success (on-success (format-success-data %)))) (defn get-on-failure [{:keys [on-failure]}] diff --git a/src/status_im/contexts/wallet/send/events.cljs b/src/status_im/contexts/wallet/send/events.cljs index 7e84c1b333..2291228f65 100644 --- a/src/status_im/contexts/wallet/send/events.cljs +++ b/src/status_im/contexts/wallet/send/events.cljs @@ -647,22 +647,38 @@ (rf/reg-event-fx :wallet/prepare-signatures-for-transactions (fn [{:keys [db]} [type sha3-pwd]] - (let [transaction-for-signing (get-in db [:wallet :ui type :transaction-for-signing])] - {:fx [[:effects.wallet/sign-transaction-hashes - {:hashes (get-in transaction-for-signing [:signingDetails :hashes]) - :address (get-in transaction-for-signing [:signingDetails :address]) - :password (security/safe-unmask-data sha3-pwd) - :on-success (fn [signatures] - (rf/dispatch [:wallet/send-router-transactions-with-signatures type - signatures])) - :on-error (fn [error] - (log/error "failed to prepare signatures for transactions" - {:event :wallet/prepare-signatures-for-transactions - :error error}) - (rf/dispatch [:toasts/upsert - {:id :prepare-signatures-for-transactions-error - :type :negative - :text (:message error)}]))}]]}))) + (let [{:keys [hashes address signOnKeycard]} (get-in db + [:wallet :ui type :transaction-for-signing + :signingDetails]) + on-success (fn [signatures] + (rf/dispatch + [:wallet/send-router-transactions-with-signatures type + signatures])) + on-error (fn [error] + (log/error + "failed to prepare signatures for transactions" + {:event :wallet/prepare-signatures-for-transactions + :error error}) + (rf/dispatch + [:toasts/upsert + {:id :prepare-signatures-for-transactions-error + :type :negative + :text (:message error)}]))] + (if signOnKeycard + {:fx [[:dispatch + [:standard-auth/authorize-with-keycard + {:on-complete #(rf/dispatch [:keycard/connect-and-sign-hashes + {:keycard-pin % + :address address + :hashes hashes + :on-success on-success + :on-failure on-error}])}]]]} + {:fx [[:effects.wallet/sign-transaction-hashes + {:hashes hashes + :address address + :password (security/safe-unmask-data sha3-pwd) + :on-success on-success + :on-error on-error}]]})))) (rf/reg-event-fx :wallet/send-router-transactions-with-signatures @@ -678,6 +694,7 @@ :params [{:uuid (get-in transaction-for-signing [:sendDetails :uuid]) :signatures signatures-map}] :on-success (fn [] + (rf/dispatch [:wallet/clean-send-data]) (rf/dispatch [:hide-bottom-sheet])) :on-error (fn [error] (log/error "failed to send router transactions with signatures" diff --git a/src/status_im/contexts/wallet/send/routes/view.cljs b/src/status_im/contexts/wallet/send/routes/view.cljs index 45b777e261..73a66a19b3 100644 --- a/src/status_im/contexts/wallet/send/routes/view.cljs +++ b/src/status_im/contexts/wallet/send/routes/view.cljs @@ -84,39 +84,40 @@ [{:keys [network-values token-symbol on-press on-long-press receiver? loading-routes? token-not-supported-in-receiver-networks?]}] [rn/view - (map-indexed (fn [index - {chain-id :chain-id - network-value-type :type - total-amount :total-amount}] - (let [status (cond (and (= network-value-type :not-available) - loading-routes? - token-not-supported-in-receiver-networks?) - :loading - (= network-value-type :not-available) - :disabled - :else network-value-type) - amount-formatted (-> (rf/sub [:wallet/send-amount-fixed total-amount]) - (str " " token-symbol))] - [rn/view - {:key (str (if receiver? "to" "from") "-" chain-id) - :style {:margin-top (if (pos? index) 11 7.5)}} - [quo/network-bridge - {:amount (if (= network-value-type :not-available) - (i18n/label :t/not-available) - amount-formatted) - :network (network-utils/id->network chain-id) - :status status - :on-press #(when (not loading-routes?) - (cond - (= network-value-type :edit) - (open-preferences) - on-press (on-press chain-id total-amount))) - :on-long-press #(when (and (not loading-routes?) (not= status :disabled)) - (cond - (= network-value-type :add) - (open-preferences) - on-long-press (on-long-press chain-id total-amount)))}]])) - network-values)]) + (doall + (map-indexed (fn [index + {chain-id :chain-id + network-value-type :type + total-amount :total-amount}] + (let [status (cond (and (= network-value-type :not-available) + loading-routes? + token-not-supported-in-receiver-networks?) + :loading + (= network-value-type :not-available) + :disabled + :else network-value-type) + amount-formatted (-> (rf/sub [:wallet/send-amount-fixed total-amount]) + (str " " token-symbol))] + [rn/view + {:key (str (if receiver? "to" "from") "-" chain-id) + :style {:margin-top (if (pos? index) 11 7.5)}} + [quo/network-bridge + {:amount (if (= network-value-type :not-available) + (i18n/label :t/not-available) + amount-formatted) + :network (network-utils/id->network chain-id) + :status status + :on-press #(when (not loading-routes?) + (cond + (= network-value-type :edit) + (open-preferences) + on-press (on-press chain-id total-amount))) + :on-long-press #(when (and (not loading-routes?) (not= status :disabled)) + (cond + (= network-value-type :add) + (open-preferences) + on-long-press (on-long-press chain-id total-amount)))}]])) + network-values))]) (defn render-network-links [{:keys [network-links sender-network-values]}] diff --git a/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs b/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs index 621588140d..b4af20266d 100644 --- a/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs +++ b/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs @@ -268,8 +268,7 @@ :transaction-type transaction-type}] (when (and (not loading-suggested-routes?) route (seq route)) [standard-auth/slide-button - {:keycard-supported? (get-in transaction-for-signing - [:signingDetails :signOnKeycard]) + {:keycard-supported? true :size :size-48 :track-text (if (= transaction-type :tx/bridge) (i18n/label :t/slide-to-bridge)