[keycard] Account generation & tx signing on simulated card
This commit is contained in:
parent
6cf242a036
commit
ee5d53eba9
|
@ -276,6 +276,16 @@ RCT_EXPORT_METHOD(multiAccountImportPrivateKey:(NSString *)json
|
|||
callback(@[result]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////// hashTransaction
|
||||
RCT_EXPORT_METHOD(hashTransaction:(NSString *)txArgsJSON
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"HashTransaction() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoHashTransaction(txArgsJSON);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////// multiAccountImportMnemonic
|
||||
RCT_EXPORT_METHOD(multiAccountImportMnemonic:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
|
|
|
@ -412,3 +412,6 @@
|
|||
|
||||
(defn login [args]
|
||||
(keycard/login card args))
|
||||
|
||||
(defn send-transaction-with-signature [args]
|
||||
(keycard/send-transaction-with-signature card args))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
(ns status-im.hardwallet.core
|
||||
(:require [status-im.hardwallet.change-pin :as change-pin]
|
||||
[status-im.hardwallet.common :as common]
|
||||
status-im.hardwallet.delete-key
|
||||
status-im.hardwallet.export-key
|
||||
[status-im.hardwallet.login :as login]
|
||||
[status-im.hardwallet.mnemonic :as mnemonic]
|
||||
[status-im.hardwallet.onboarding :as onboarding]
|
||||
|
|
|
@ -100,8 +100,7 @@
|
|||
|
||||
(re-frame/reg-fx
|
||||
:send-transaction-with-signature
|
||||
(fn [{:keys [transaction signature on-completed]}]
|
||||
(status/send-transaction-with-signature transaction signature on-completed)))
|
||||
card/send-transaction-with-signature)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:hardwallet/persist-pairings
|
||||
|
|
|
@ -29,4 +29,5 @@
|
|||
(get-keys [this args])
|
||||
(sign [this args])
|
||||
(save-multiaccount-and-login [this args])
|
||||
(login [this args]))
|
||||
(login [this args])
|
||||
(send-transaction-with-signature [this args]))
|
||||
|
|
|
@ -29,4 +29,5 @@
|
|||
(sign [this args])
|
||||
(sign-typed-data [this args])
|
||||
(save-multiaccount-and-login [this args])
|
||||
(login [this args]))
|
||||
(login [this args])
|
||||
(send-transaction-with-signature [this args]))
|
||||
|
|
|
@ -211,6 +211,10 @@
|
|||
(defn login [args]
|
||||
(status/login-with-keycard args))
|
||||
|
||||
(defn send-transaction-with-signature
|
||||
[{:keys [transaction signature on-completed]}]
|
||||
(status/send-transaction-with-signature transaction signature on-completed))
|
||||
|
||||
(defrecord RealKeycard []
|
||||
keycard/Keycard
|
||||
(keycard/check-nfc-support [this args]
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
(ns status-im.hardwallet.simulated-keycard
|
||||
(:require [re-frame.db :as re-frame.db]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[re-frame.db :as re-frame.db]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.hardwallet.keycard :as keycard]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.utils.types :as types]
|
||||
[status-im.utils.utils :as utils]))
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.i18n :as i18n]
|
||||
[clojure.string :as string]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def initial-state
|
||||
{:card-connected? false
|
||||
|
@ -23,7 +27,7 @@
|
|||
{:free-pairing-slots 5
|
||||
:app-version "2.2"
|
||||
:secure-channel-pub-key "04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e",
|
||||
:instance-uid "9c3f27ee5dfc39c2b14f4d6d3379cd68"
|
||||
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
|
||||
:paired? true
|
||||
:has-master-key? true
|
||||
:initialized? true
|
||||
|
@ -79,20 +83,22 @@
|
|||
(defn install-applet [_])
|
||||
(defn install-cash-applet [_])
|
||||
|
||||
(def kk1-password "6d9ZHjn94kFP4bPm")
|
||||
(def kk1-password "000000")
|
||||
|
||||
(defn init-card [{:keys [pin on-success]}]
|
||||
(swap! state assoc :application-info
|
||||
{:free-pairing-slots 5
|
||||
:app-version "2.2"
|
||||
:secure-channel-pub-key "04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e", :key-uid "", :instance-uid "9c3f27ee5dfc39c2b14f4d6d3379cd68"
|
||||
:secure-channel-pub-key "04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e",
|
||||
:key-uid "",
|
||||
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
|
||||
:paired? false
|
||||
:has-master-key? false
|
||||
:initialized? true})
|
||||
(swap! state assoc :pin pin)
|
||||
(later
|
||||
#(on-success {:password kk1-password
|
||||
:puk "320612366918"
|
||||
:puk "000000000000"
|
||||
:pin pin})))
|
||||
|
||||
(defn install-applet-and-init-card [_])
|
||||
|
@ -111,7 +117,21 @@
|
|||
multiaccount
|
||||
whisper (get derived constants/path-whisper-keyword)
|
||||
wallet (get derived constants/path-default-wallet-keyword)
|
||||
password (ethereum/sha3 pin)]
|
||||
wallet-root (get derived constants/path-wallet-root-keyword)
|
||||
password (ethereum/sha3 pin)
|
||||
response {:key-uid key-uid
|
||||
:encryption-public-key (ethereum/sha3 pin)
|
||||
:address address
|
||||
:whisper-public-key (:public-key whisper)
|
||||
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
|
||||
:wallet-root-public-key (:public-key wallet-root)
|
||||
:wallet-root-address (:address wallet-root)
|
||||
:whisper-address (:address whisper)
|
||||
:public-key public-key
|
||||
:whisper-private-key "34bc7d0c258c4f2ac1dac4fd6c55c9478bac1f4a9d8b9f1152c8551ab7187b43"
|
||||
:wallet-address (:address wallet)
|
||||
:wallet-public-key (:public-key wallet)}]
|
||||
(log/debug "[simulated kk] generate-and-load-key response" response)
|
||||
(status/multiaccount-store-derived
|
||||
id
|
||||
[constants/path-wallet-root
|
||||
|
@ -119,19 +139,7 @@
|
|||
constants/path-whisper
|
||||
constants/path-default-wallet]
|
||||
password
|
||||
#(on-success
|
||||
{:key-uid key-uid
|
||||
:encryption-public-key (ethereum/sha3 pin)
|
||||
:address address
|
||||
:whisper-public-key (:public-key whisper)
|
||||
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
|
||||
:wallet-root-public-key "0463187f5c917eef481e04af704c14e57a9e8596516f0ec10a4556561ad49b5aa249976ec545d37d04f4d4c7d1c0d9a2141dc61e458b09631d25fa7858c6323ea3"
|
||||
:wallet-root-address "e034a084d2282e265f83e3fdfa48b42c3d53312a"
|
||||
:whisper-address (:address whisper)
|
||||
:public-key public-key
|
||||
:whisper-private-key "34bc7d0c258c4f2ac1dac4fd6c55c9478bac1f4a9d8b9f1152c8551ab7187b43"
|
||||
:wallet-address (:address wallet)
|
||||
:wallet-public-key (:public-key wallet)})))))
|
||||
#(on-success response)))))
|
||||
|
||||
(defn unblock-pin [_])
|
||||
|
||||
|
@ -140,22 +148,70 @@
|
|||
(= pin (get @state :pin)))
|
||||
(later #(on-success 3))))
|
||||
|
||||
(defn change-pin [_])
|
||||
(defn unpair [_])
|
||||
(defn delete [_])
|
||||
(defn remove-key [_])
|
||||
(defn remove-key-with-unpair [_])
|
||||
(defn export-key [_])
|
||||
(defn change-pin [args]
|
||||
(log/warn "change-pin not implemented" args))
|
||||
(defn unpair [args]
|
||||
(log/warn "unpair not implemented" args))
|
||||
(defn delete [args]
|
||||
(log/warn "delete not implemented" args))
|
||||
(defn remove-key [args]
|
||||
(log/warn "remove-key not implemented" args))
|
||||
(defn remove-key-with-unpair [args]
|
||||
(log/warn "remove-key-with-unpair not implemented" args))
|
||||
|
||||
(defn normalize-path [path]
|
||||
(if (string/starts-with? path "m/")
|
||||
(str constants/path-wallet-root
|
||||
"/" (last (string/split path "/")))
|
||||
path))
|
||||
|
||||
(defn export-key [{:keys [pin on-success on-failure]}]
|
||||
(let [wallet-root-address (get-in
|
||||
@re-frame.db/app-db
|
||||
[:multiaccount :wallet-root-address])
|
||||
accounts (get @re-frame.db/app-db :multiaccount/accounts)
|
||||
hashed-password (ethereum/sha3 pin)
|
||||
path-num (inc (get-in @re-frame.db/app-db [:multiaccount :latest-derived-path]))
|
||||
path (str "m/" path-num)]
|
||||
(status/multiaccount-load-account
|
||||
wallet-root-address
|
||||
hashed-password
|
||||
(fn [value]
|
||||
(let [{:keys [id error]} (types/json->clj value)]
|
||||
(if error
|
||||
(re-frame/dispatch [::new-account-error :password-error error])
|
||||
(status/multiaccount-derive-addresses
|
||||
id
|
||||
[path]
|
||||
(fn [derived]
|
||||
(let [derived-address (get-in (types/json->clj derived) [(keyword path) :address])]
|
||||
(if (some #(= derived-address (get % :address)) accounts)
|
||||
(re-frame/dispatch [::new-account-error :account-error (i18n/label :t/account-exists-title)])
|
||||
(status/multiaccount-store-derived
|
||||
id
|
||||
[path]
|
||||
hashed-password
|
||||
(fn [result]
|
||||
(let [{:keys [error] :as result} (types/json->clj result)
|
||||
{:keys [publicKey]} (get result (keyword path))]
|
||||
(if error
|
||||
(on-failure error)
|
||||
(on-success publicKey)))))))))))))))
|
||||
|
||||
(defn unpair-and-delete [_])
|
||||
(defn get-keys [{:keys [on-success pin]}]
|
||||
(swap! state assoc :pin pin)
|
||||
;;TODO(rasom): verify password before callback
|
||||
(later
|
||||
#(on-success
|
||||
{:key-uid (get-in @state [:application-info :key-uid])
|
||||
:encryption-public-key (ethereum/sha3 pin)})))
|
||||
|
||||
(defn sign [_])
|
||||
(defn sign-typed-data [_])
|
||||
(defn sign [{:keys [on-success]}]
|
||||
(on-success "123"))
|
||||
|
||||
(defn sign-typed-data [args]
|
||||
(log/warn "sign-typed-data not implemented" args))
|
||||
|
||||
(defn save-multiaccount-and-login
|
||||
[{:keys [multiaccount-data password settings node-config accounts-data]}]
|
||||
|
@ -169,6 +225,10 @@
|
|||
(defn login [{:keys [multiaccount-data password]}]
|
||||
(status/login multiaccount-data password))
|
||||
|
||||
(defn send-transaction-with-signature
|
||||
[{:keys [transaction on-completed]}]
|
||||
(status/send-transaction transaction (ethereum/sha3 (:pin @state)) on-completed))
|
||||
|
||||
(defrecord SimulatedKeycard []
|
||||
keycard/Keycard
|
||||
(keycard/check-nfc-support [this args]
|
||||
|
@ -224,4 +284,6 @@
|
|||
(keycard/save-multiaccount-and-login [this args]
|
||||
(save-multiaccount-and-login args))
|
||||
(keycard/login [this args]
|
||||
(login args)))
|
||||
(login args))
|
||||
(keycard/send-transaction-with-signature [this args]
|
||||
(send-transaction-with-signature args)))
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
[status-im.hardwallet.common :as common]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]))
|
||||
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
|
||||
[status-im.utils.hex :as utils.hex]))
|
||||
|
||||
(fx/defn show-pin-sheet
|
||||
{:events [:hardwallet/new-account-pin-sheet]}
|
||||
|
@ -41,10 +42,14 @@
|
|||
(assoc-in
|
||||
db [:hardwallet :on-export-success]
|
||||
#(vector :wallet.accounts/account-stored
|
||||
(let [public-key (utils.hex/normalize-hex %)]
|
||||
{;; Strip leading 04 prefix denoting uncompressed key format
|
||||
:address (eip55/address->checksum (str "0x" (ethereum/public-key->address (subs % 2))))
|
||||
:public-key (str "0x" %)
|
||||
:path path}))
|
||||
:address (eip55/address->checksum
|
||||
(str "0x"
|
||||
(ethereum/public-key->address
|
||||
(subs public-key 2))))
|
||||
:public-key (str "0x" public-key)
|
||||
:path path})))
|
||||
|
||||
:hardwallet/export-key {:pin pin :pairing pairing :path path}}))
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.navigation :as navigation]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.security :as security]
|
||||
|
@ -39,7 +40,8 @@
|
|||
(defn inc-step [step]
|
||||
(let [inverted (map-invert step-kw-to-num)]
|
||||
(if (and (= step :choose-key)
|
||||
(or (not platform/android?)
|
||||
(or (not (or platform/android?
|
||||
config/keycard-test-menu-enabled?))
|
||||
(not (nfc/nfc-supported?))))
|
||||
:create-code
|
||||
(inverted (inc (step-kw-to-num step))))))
|
||||
|
@ -320,7 +322,9 @@
|
|||
(status/multiaccount-generate-and-derive-addresses
|
||||
5
|
||||
12
|
||||
[constants/path-whisper constants/path-default-wallet]
|
||||
[constants/path-whisper
|
||||
constants/path-wallet-root
|
||||
constants/path-default-wallet]
|
||||
#(re-frame/dispatch [:intro-wizard/on-keys-generated
|
||||
(mapv normalize-multiaccount-data-keys
|
||||
(types/json->clj %))]))))
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
|
||||
[taoensso.timbre :as log]))
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(defn existing-account?
|
||||
[multiaccounts key-uid]
|
||||
|
@ -250,7 +251,8 @@
|
|||
assoc :step :select-key-storage
|
||||
:forward-action :multiaccounts.recover/select-storage-next-pressed
|
||||
:selected-storage-type :default)}
|
||||
(if (and platform/android?
|
||||
(if (and (or platform/android?
|
||||
config/keycard-test-menu-enabled?)
|
||||
(nfc/nfc-supported?))
|
||||
(navigation/navigate-to-cofx :recover-multiaccount-select-storage nil)
|
||||
(select-storage-next-pressed))))
|
||||
|
|
|
@ -176,8 +176,13 @@
|
|||
(i18n/label type)]]
|
||||
[react/touchable-highlight
|
||||
{:accessibility-label (keyword (str "select-storage-" type))
|
||||
:on-press #(re-frame/dispatch [:intro-wizard/on-key-storage-selected (if (and config/hardwallet-enabled?
|
||||
platform/android?) type :default)])}
|
||||
:on-press #(re-frame/dispatch
|
||||
[:intro-wizard/on-key-storage-selected
|
||||
(if (and config/hardwallet-enabled?
|
||||
(or platform/android?
|
||||
config/keycard-test-menu-enabled?))
|
||||
type
|
||||
:default)])}
|
||||
[react/view (assoc (styles/list-item selected?)
|
||||
:align-items :flex-start
|
||||
:padding-top 16
|
||||
|
|
|
@ -50,7 +50,8 @@
|
|||
:icon :main-icons/text
|
||||
:on-press #(re-frame/dispatch [::multiaccounts.recover/enter-phrase-pressed])}]
|
||||
(when (and config/hardwallet-enabled?
|
||||
platform/android?
|
||||
(or platform/android?
|
||||
config/keycard-test-menu-enabled?)
|
||||
(nfc/nfc-supported?))
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
|
|
|
@ -138,7 +138,8 @@
|
|||
:accessibility-label :sync-settings-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :sync-settings])}
|
||||
(when (and platform/android?
|
||||
(when (and (or platform/android?
|
||||
config/keycard-test-menu-enabled?)
|
||||
config/hardwallet-enabled?
|
||||
keycard-account?)
|
||||
{:icon :main-icons/keycard
|
||||
|
|
|
@ -136,14 +136,8 @@
|
|||
path-num (inc (get-in db [:multiaccount :latest-derived-path]))
|
||||
accounts (:multiaccount/accounts db)]
|
||||
{:db (assoc-in db [:add-account :step] :generating)
|
||||
::generate-account {:derivation-info (if wallet-root-address
|
||||
;; Use the walllet-root-address for stored on disk keys
|
||||
;; This needs to be the RELATIVE path to the key used to derive
|
||||
{:path (str "m/" path-num)
|
||||
::generate-account {:derivation-info {:path (str "m/" path-num)
|
||||
:address wallet-root-address}
|
||||
;; Fallback on the master account for keycards, use the absolute path
|
||||
{:path (str constants/path-wallet-root "/" path-num)
|
||||
:address (get-in db [:multiaccount :address])})
|
||||
:hashed-password hashed-password
|
||||
:accounts accounts}}))
|
||||
|
||||
|
|
Loading…
Reference in New Issue