[simulated kk] Add proper signing for send/request transaction messages

This commit is contained in:
Roman Volosovskyi 2020-06-25 14:16:24 +03:00
parent ca75a7a057
commit 7f1e25a515
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
5 changed files with 64 additions and 27 deletions

View File

@ -4,7 +4,8 @@
[status-im.utils.types :as types] [status-im.utils.types :as types]
[status-im.native-module.core :as status] [status-im.native-module.core :as status]
[status-im.ethereum.core :as ethereum] [status-im.ethereum.core :as ethereum]
[status-im.hardwallet.keycard :as keycard])) [status-im.hardwallet.keycard :as keycard]
[taoensso.timbre :as log]))
(defonce event-emitter (.-DeviceEventEmitter rn)) (defonce event-emitter (.-DeviceEventEmitter rn))
(defonce active-listeners (atom [])) (defonce active-listeners (atom []))
@ -191,6 +192,7 @@
(defn sign (defn sign
[{:keys [pairing pin path hash on-success on-failure]}] [{:keys [pairing pin path hash on-success on-failure]}]
(log/debug "keycard sign" "path" path)
(when (and pairing pin hash) (when (and pairing pin hash)
(if path (if path
(.. status-keycard (.. status-keycard

View File

@ -1,13 +1,13 @@
(ns status-im.hardwallet.sign (ns status-im.hardwallet.sign
(:require [clojure.string :as string] (:require [re-frame.core :as re-frame]
[re-frame.core :as re-frame]
[status-im.ethereum.core :as ethereum] [status-im.ethereum.core :as ethereum]
[status-im.ethereum.json-rpc :as json-rpc] [status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.utils.money :as money] [status-im.utils.money :as money]
[status-im.utils.types :as types] [status-im.utils.types :as types]
[taoensso.timbre :as log] [taoensso.timbre :as log]
[status-im.hardwallet.common :as common])) [status-im.hardwallet.common :as common]
[clojure.string :as clojure.string]))
(fx/defn sign (fx/defn sign
{:events [:hardwallet/sign]} {:events [:hardwallet/sign]}
@ -18,6 +18,7 @@
instance-uid (get-in db [:hardwallet :application-info :instance-uid]) instance-uid (get-in db [:hardwallet :application-info :instance-uid])
keycard-match? (= keycard-instance-uid instance-uid) keycard-match? (= keycard-instance-uid instance-uid)
hash (get-in db [:hardwallet :hash]) hash (get-in db [:hardwallet :hash])
data (get-in db [:hardwallet :data])
pin (common/vector->string (get-in db [:hardwallet :pin :sign])) pin (common/vector->string (get-in db [:hardwallet :pin :sign]))
from (get-in db [:signing/tx :from :address]) from (get-in db [:signing/tx :from :address])
path (reduce path (reduce
@ -32,6 +33,7 @@
(assoc-in [:hardwallet :card-read-in-progress?] true) (assoc-in [:hardwallet :card-read-in-progress?] true)
(assoc-in [:hardwallet :pin :status] :verifying)) (assoc-in [:hardwallet :pin :status] :verifying))
:hardwallet/sign {:hash (ethereum/naked-address hash) :hardwallet/sign {:hash (ethereum/naked-address hash)
:data data
:pairing pairing :pairing pairing
:pin pin :pin pin
:path path}} :path path}}
@ -59,6 +61,7 @@
(assoc-in [:hardwallet :card-read-in-progress?] true) (assoc-in [:hardwallet :card-read-in-progress?] true)
(assoc-in [:hardwallet :pin :status] :verifying)) (assoc-in [:hardwallet :pin :status] :verifying))
:hardwallet/sign {:hash (ethereum/naked-address hash) :hardwallet/sign {:hash (ethereum/naked-address hash)
:data (:data params)
:pairing pairing :pairing pairing
:pin pin :pin pin
:on-success on-success}} :on-success on-success}}
@ -77,6 +80,7 @@
(if message-id (if message-id
[:sign/send-accept-transaction-message message-id tx-hash signature] [:sign/send-accept-transaction-message message-id tx-hash signature]
[:sign/send-transaction-message chat-id value contract tx-hash signature]) [:sign/send-transaction-message chat-id value contract tx-hash signature])
:signing/show-transaction-result nil
:db (-> db :db (-> db
(assoc-in [:hardwallet :pin :sign] []) (assoc-in [:hardwallet :pin :sign] [])
(assoc-in [:hardwallet :pin :status] nil))} (assoc-in [:hardwallet :pin :status] nil))}
@ -144,14 +148,8 @@
(fx/defn sign-message-completed (fx/defn sign-message-completed
[_ signature] [_ signature]
(let [signature' (-> signature {:dispatch
; add 27 to last byte [:signing/sign-message-completed signature]})
; https://github.com/ethereum/go-ethereum/blob/master/internal/ethapi/api.go#L431
(clojure.string/replace-first #"00$", "1b")
(clojure.string/replace-first #"01$", "1c")
(ethereum/normalized-hex))]
{:dispatch
[:signing/sign-message-completed (types/clj->json {:result signature'})]}))
(fx/defn send-transaction-with-signature (fx/defn send-transaction-with-signature
[_ data] [_ data]
@ -161,9 +159,14 @@
{:events [:hardwallet.callback/on-sign-success]} {:events [:hardwallet.callback/on-sign-success]}
[{:keys [db] :as cofx} signature] [{:keys [db] :as cofx} signature]
(log/debug "[hardwallet] sign success: " signature) (log/debug "[hardwallet] sign success: " signature)
(let [transaction (get-in db [:hardwallet :transaction]) (let [signature-json (types/clj->json
tx-obj (select-keys transaction [:from :to :value :gas :gasPrice :command? :chat-id :message-id]) {:result (-> signature
command? (:command? transaction)] (clojure.string/replace-first #"00$", "1b")
(clojure.string/replace-first #"01$", "1c")
ethereum/normalized-hex)})
transaction (get-in db [:hardwallet :transaction])
tx-obj (select-keys transaction [:from :to :value :gas :gasPrice :command? :chat-id :message-id])
command? (:command? transaction)]
(fx/merge cofx (fx/merge cofx
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :hash] nil) (assoc-in [:hardwallet :hash] nil)
@ -179,10 +182,11 @@
(common/get-application-info (common/get-pairing db) nil) (common/get-application-info (common/get-pairing db) nil)
(common/hide-connection-sheet)))) (common/hide-connection-sheet))))
(if transaction (if transaction
(send-transaction-with-signature {:transaction (types/clj->json transaction) (send-transaction-with-signature
:signature signature {:transaction (types/clj->json transaction)
:on-completed #(re-frame/dispatch [:signing/transaction-completed % tx-obj])}) :signature signature
(sign-message-completed signature))))) :on-completed #(re-frame/dispatch [:signing/transaction-completed % tx-obj])})
(sign-message-completed signature-json)))))
(fx/defn on-sign-error (fx/defn on-sign-error
{:events [:hardwallet.callback/on-sign-error]} {:events [:hardwallet.callback/on-sign-error]}

View File

@ -254,10 +254,32 @@
#js {:code "EUNSPECIFIED" #js {:code "EUNSPECIFIED"
:message "Unexpected error SW, 0x63C2"}))))) :message "Unexpected error SW, 0x63C2"})))))
(defn sign [{:keys [pin on-success on-failure]}] (defn sign [{:keys [pin hash data path on-success on-failure]}]
(if (= pin (get @state :pin)) (if (= pin (get @state :pin))
(later (later
#(on-success "123")) #(let [address
(if path
(reduce
(fn [_ {:keys [address] :as acc}]
(when (= path (:path acc))
(reduced address)))
nil
(:multiaccount/accounts @re-frame.db/app-db))
(-> (:multiaccount/accounts @re-frame.db/app-db)
first
:address))
params (types/clj->json
{:account address
:password (ethereum/sha3 pin)
:data (or data (str "0x" hash))})]
(status/sign-message
params
(fn [res]
(let [signature (-> res
types/json->clj
:result
ethereum/normalized-hex)]
(on-success signature))))))
(do (do
(swap! state update-in (swap! state update-in
[:application-info :pin-retry-counter] [:application-info :pin-retry-counter]

View File

@ -271,7 +271,8 @@
:message-id message-id :message-id message-id
:chat-id chat-id :chat-id chat-id
:value value :value value
:contract contract} :contract contract
:data data}
hash]))}) hash]))})
(fn [_] (fn [_]
{:signing.fx/sign-message {:signing.fx/sign-message

View File

@ -43,18 +43,26 @@
{::hash-typed-data {::hash-typed-data
{:data data {:data data
:on-completed :on-completed
(or on-completed #(re-frame/dispatch [:signing.keycard.callback/hash-message-completed %]))}} (or on-completed
#(re-frame/dispatch
[:signing.keycard.callback/hash-message-completed
data typed? %]))}}
{::hash-message {::hash-message
{:message data {:message data
:on-completed :on-completed
(or on-completed #(re-frame/dispatch [:signing.keycard.callback/hash-message-completed %]))}})) (or on-completed
#(re-frame/dispatch
[:signing.keycard.callback/hash-message-completed
data typed? %]))}}))
(fx/defn hash-message-completed (fx/defn hash-message-completed
{:events [:signing.keycard.callback/hash-message-completed]} {:events [:signing.keycard.callback/hash-message-completed]}
[{:keys [db]} result] [{:keys [db]} data typed? result]
(let [{:keys [result error]} (types/json->clj result)] (let [{:keys [result error]} (types/json->clj result)]
{:db (-> db {:db (update db :hardwallet assoc
(assoc-in [:hardwallet :hash] result))})) :hash result
:type? typed?
:data data)}))
(fx/defn hash-transaction (fx/defn hash-transaction
[{:keys [db]}] [{:keys [db]}]