- ensure that `:key-uid` is always added to `app-db` with proper case - tests which cover multiacc duplication case
This commit is contained in:
parent
e5f7a94ee2
commit
9a713148c7
|
@ -1846,20 +1846,20 @@
|
|||
(assoc :intro-wizard nil))}
|
||||
(multiaccounts.create/on-multiaccount-created
|
||||
{:derived {constants/path-wallet-root-keyword
|
||||
{:publicKey wallet-root-public-key
|
||||
{:public-key wallet-root-public-key
|
||||
:address (eip55/address->checksum wallet-root-address)}
|
||||
constants/path-whisper-keyword
|
||||
{:publicKey whisper-public-key
|
||||
{:public-key whisper-public-key
|
||||
:address (eip55/address->checksum whisper-address)
|
||||
:name name
|
||||
:photo-path photo-path}
|
||||
constants/path-default-wallet-keyword
|
||||
{:publicKey wallet-public-key
|
||||
{:public-key wallet-public-key
|
||||
:address (eip55/address->checksum wallet-address)}}
|
||||
:address address
|
||||
:public-key public-key
|
||||
:keycard-instance-uid instance-uid
|
||||
:keyUid (ethereum/normalized-hex key-uid)
|
||||
:key-uid (ethereum/normalized-hex key-uid)
|
||||
:keycard-pairing pairing
|
||||
:keycard-paired-on paired-on
|
||||
:chat-key whisper-private-key}
|
||||
|
|
|
@ -51,13 +51,30 @@
|
|||
(let [{:keys [selected-id multiaccounts]} (:intro-wizard db)]
|
||||
(some #(when (= selected-id (:id %)) %) multiaccounts)))
|
||||
|
||||
(defn normalize-derived-data-keys [derived-data]
|
||||
(->> derived-data
|
||||
(map (fn [[path {:keys [publicKey] :as data}]]
|
||||
[path (cond-> (-> data
|
||||
(dissoc :publicKey)
|
||||
(assoc :public-key publicKey)))]))
|
||||
(into {})))
|
||||
|
||||
(defn normalize-multiaccount-data-keys
|
||||
[{:keys [publicKey keyUid derived] :as data}]
|
||||
(cond-> (-> data
|
||||
(dissoc :keyUid :publicKey)
|
||||
(assoc :key-uid keyUid
|
||||
:public-key publicKey))
|
||||
derived
|
||||
(update :derived normalize-derived-data-keys)))
|
||||
|
||||
(fx/defn create-multiaccount
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [selected-id key-code]} (:intro-wizard db)
|
||||
hashed-password (ethereum/sha3 (security/safe-unmask-data key-code))
|
||||
callback (fn [result]
|
||||
(let [derived-data (types/json->clj result)
|
||||
public-key (get-in derived-data [constants/path-whisper-keyword :publicKey])]
|
||||
(let [derived-data (normalize-derived-data-keys (types/json->clj result))
|
||||
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
|
||||
(status/gfycat-identicon-async
|
||||
public-key
|
||||
(fn [name photo-path]
|
||||
|
@ -191,17 +208,17 @@
|
|||
|
||||
(defn prepare-accounts-data
|
||||
[multiaccount]
|
||||
[(let [{:keys [publicKey address]}
|
||||
[(let [{:keys [public-key address]}
|
||||
(get-in multiaccount [:derived constants/path-default-wallet-keyword])]
|
||||
{:public-key publicKey
|
||||
{:public-key public-key
|
||||
:address (eip55/address->checksum address)
|
||||
:color colors/blue
|
||||
:wallet true
|
||||
:path constants/path-default-wallet
|
||||
:name "Status account"})
|
||||
(let [{:keys [publicKey address name photo-path]}
|
||||
(let [{:keys [public-key address name photo-path]}
|
||||
(get-in multiaccount [:derived constants/path-whisper-keyword])]
|
||||
{:public-key publicKey
|
||||
{:public-key public-key
|
||||
:address (eip55/address->checksum address)
|
||||
:name name
|
||||
:photo-path photo-path
|
||||
|
@ -227,7 +244,7 @@
|
|||
|
||||
(fx/defn on-multiaccount-created
|
||||
[{:keys [signing-phrase random-guid-generator db] :as cofx}
|
||||
{:keys [address chat-key keycard-instance-uid keyUid
|
||||
{:keys [address chat-key keycard-instance-uid key-uid
|
||||
keycard-pairing keycard-paired-on mnemonic public-key]
|
||||
:as multiaccount}
|
||||
password
|
||||
|
@ -236,7 +253,7 @@
|
|||
multiaccount-data {:name name
|
||||
:address address
|
||||
:photo-path photo-path
|
||||
:key-uid keyUid
|
||||
:key-uid key-uid
|
||||
:keycard-pairing keycard-pairing}
|
||||
keycard-multiaccount? (boolean keycard-pairing)
|
||||
eip1581-address (get-in multiaccount [:derived
|
||||
|
@ -247,7 +264,7 @@
|
|||
{;; address of the master key
|
||||
:address address
|
||||
;; sha256 of master public key
|
||||
:key-uid keyUid
|
||||
:key-uid key-uid
|
||||
;; The address from which we derive any wallet
|
||||
:wallet-root-address
|
||||
(get-in multiaccount [:derived
|
||||
|
@ -274,7 +291,7 @@
|
|||
:keycard-pairing keycard-pairing
|
||||
:keycard-paired-on keycard-paired-on))
|
||||
db (assoc db
|
||||
:multiaccounts/login {:key-uid keyUid
|
||||
:multiaccounts/login {:key-uid key-uid
|
||||
:name name
|
||||
:photo-path photo-path
|
||||
:password password
|
||||
|
@ -311,7 +328,9 @@
|
|||
5
|
||||
12
|
||||
[constants/path-whisper constants/path-default-wallet]
|
||||
#(re-frame/dispatch [:intro-wizard/on-keys-generated (types/json->clj %)]))))
|
||||
#(re-frame/dispatch [:intro-wizard/on-keys-generated
|
||||
(mapv normalize-multiaccount-data-keys
|
||||
(types/json->clj %))]))))
|
||||
|
||||
(fx/defn on-keys-generated
|
||||
{:events [:intro-wizard/on-keys-generated]}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
(spec/def :multiaccount/accounts (spec/coll-of :multiaccount/account :kind vector?))
|
||||
|
||||
(spec/def :multiaccount/address :global/address)
|
||||
(spec/def :multiaccount/key-uid string?)
|
||||
(spec/def :multiaccount/key-uid :global/key-uid)
|
||||
(spec/def :multiaccount/name :global/not-empty-string)
|
||||
(spec/def :multiaccount/public-key :global/public-key)
|
||||
(spec/def :multiaccount/signed-up? (spec/nilable boolean?))
|
||||
|
@ -76,6 +76,20 @@
|
|||
:multiaccount/keycard-paired-on
|
||||
:multiaccount/root-address
|
||||
:multiaccount/accounts]))
|
||||
;; generated multiaccounts
|
||||
(spec/def :generated-multiaccounts/id string?)
|
||||
(spec/def :generated-multiaccounts/derived-key
|
||||
(spec/keys :req-un [:multiaccount/address
|
||||
:multiaccount/public-key]))
|
||||
(spec/def :generated-multiaccounts/derived
|
||||
(spec/map-of keyword? :generated-multiaccounts/derived-key))
|
||||
(spec/def :multiaccounts/generated-multiaccount
|
||||
(spec/keys :req-un [:multiaccount/address
|
||||
:multiaccount/mnemonic
|
||||
:multiaccount/public-key
|
||||
:multiaccount/key-uid
|
||||
:generated-multiaccounts/id]
|
||||
:opt-un [:generated-multiaccounts/derived]))
|
||||
|
||||
;;used during recovering multiaccount
|
||||
(spec/def :multiaccounts/recover (spec/nilable map?))
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn existing-account?
|
||||
[root-key multiaccounts]
|
||||
(contains? multiaccounts (:keyUid root-key)))
|
||||
[multiaccounts key-uid]
|
||||
{:pre [(not (nil? key-uid))]}
|
||||
(contains? multiaccounts key-uid))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::validate-mnemonic
|
||||
|
@ -100,7 +101,9 @@
|
|||
passphrase
|
||||
password
|
||||
(fn [result]
|
||||
(let [{:keys [id] :as root-data} (types/json->clj result)]
|
||||
(let [{:keys [id] :as root-data}
|
||||
(multiaccounts.create/normalize-multiaccount-data-keys
|
||||
(types/json->clj result))]
|
||||
(status-im.native-module.core/multiaccount-derive-addresses
|
||||
id
|
||||
[constants/path-wallet-root
|
||||
|
@ -108,13 +111,16 @@
|
|||
constants/path-whisper
|
||||
constants/path-default-wallet]
|
||||
(fn [result]
|
||||
(let [derived-data (types/json->clj result)
|
||||
public-key (get-in derived-data [constants/path-whisper-keyword :publicKey])]
|
||||
(let [derived-data (multiaccounts.create/normalize-derived-data-keys
|
||||
(types/json->clj result))
|
||||
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
|
||||
(status/gfycat-identicon-async
|
||||
public-key
|
||||
(fn [name photo-path]
|
||||
(let [derived-whisper (derived-data constants/path-whisper-keyword)
|
||||
derived-data-extended (assoc-in derived-data [constants/path-whisper-keyword] (merge derived-whisper {:name name :photo-path photo-path}))]
|
||||
(let [derived-data-extended
|
||||
(update derived-data
|
||||
constants/path-whisper-keyword
|
||||
merge {:name name :photo-path photo-path})]
|
||||
(re-frame/dispatch [::import-multiaccount-success
|
||||
root-data derived-data-extended]))))))))))))
|
||||
|
||||
|
@ -130,7 +136,7 @@
|
|||
|
||||
(fx/defn on-import-multiaccount-success
|
||||
{:events [::import-multiaccount-success]}
|
||||
[{:keys [db] :as cofx} root-data derived-data]
|
||||
[{:keys [db] :as cofx} {:keys [key-uid] :as root-data} derived-data]
|
||||
(let [multiaccounts (:multiaccounts/multiaccounts db)]
|
||||
(fx/merge
|
||||
cofx
|
||||
|
@ -139,8 +145,8 @@
|
|||
:derived derived-data
|
||||
:step :recovery-success
|
||||
:forward-action :multiaccounts.recover/re-encrypt-pressed)}
|
||||
(when (existing-account? root-data multiaccounts)
|
||||
(show-existing-multiaccount-alert (:keyUid root-data)))
|
||||
(when (existing-account? multiaccounts key-uid)
|
||||
(show-existing-multiaccount-alert key-uid))
|
||||
(navigation/navigate-to-cofx :recover-multiaccount-success nil))))
|
||||
|
||||
(fx/defn enter-phrase-pressed
|
||||
|
|
|
@ -265,7 +265,7 @@
|
|||
:intro-wizard/recovery-success
|
||||
:<- [:intro-wizard]
|
||||
(fn [wizard-state]
|
||||
{:pubkey (get-in wizard-state [:derived constants/path-whisper-keyword :publicKey])
|
||||
{:pubkey (get-in wizard-state [:derived constants/path-whisper-keyword :public-key])
|
||||
:name (get-in wizard-state [:derived constants/path-whisper-keyword :name])
|
||||
:photo-path (get-in wizard-state [:derived constants/path-whisper-keyword :photo-path])
|
||||
:processing? (:processing? wizard-state)}))
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
status-im.browser.db
|
||||
status-im.ui.screens.add-new.new-public-chat.db
|
||||
status-im.ui.components.bottom-sheet.core
|
||||
status-im.ui.screens.intro.db
|
||||
[status-im.wallet.db :as wallet.db]))
|
||||
|
||||
;; initial state of app-db
|
||||
|
@ -314,4 +315,5 @@
|
|||
::collectibles
|
||||
:registry/registry
|
||||
::two-pane-ui-enabled?
|
||||
::add-account]))
|
||||
::add-account
|
||||
:intro-wizard/intro-wizard]))
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
(ns status-im.ui.screens.intro.db
|
||||
(:require [cljs.spec.alpha :as spec]
|
||||
status-im.multiaccounts.db))
|
||||
|
||||
(spec/def :intro-wizrad/encrypt-with-password? boolean?)
|
||||
(spec/def :intro-wizard/multiaccounts
|
||||
(spec/coll-of :multiaccounts/generated-multiaccount))
|
||||
(spec/def :intro-wizard/selected-storage-type? keyword?)
|
||||
(spec/def :intro-wizard/selected-id :generated-multiaccounts/id)
|
||||
(spec/def :intro-wizard/back-action keyword?)
|
||||
(spec/def :intro-wizard/weak-password? boolean?)
|
||||
(spec/def :intro-wizard/forward-action keyword?)
|
||||
(spec/def :intro-wizard/first-time-setup? boolean?)
|
||||
(spec/def :intro-wizard/step (spec/nilable keyword?))
|
||||
(spec/def :intro-wizard/root-key :multiaccounts/generated-multiaccount)
|
||||
(spec/def :intro-wizard/passphrase string?)
|
||||
(spec/def :intro-wizard/recovering? boolean?)
|
||||
(spec/def :intro-wizard/passphrase-word-count int?)
|
||||
(spec/def :intro-wizard/derived :generated-multiaccounts/derived)
|
||||
(spec/def :intro-wizard/next-button-disabled? boolean?)
|
||||
|
||||
(spec/def :intro-wizard/intro-wizard
|
||||
(spec/keys :req-un [:intro-wizrad/encrypt-with-password?
|
||||
:intro-wizard/back-action
|
||||
:intro-wizard/weak-password?
|
||||
:intro-wizard/forward-action
|
||||
:intro-wizard/first-time-setup?
|
||||
:intro-wizard/step]
|
||||
:opt-un [:intro-wizard/selected-id
|
||||
:intro-wizard/selected-storage-type?
|
||||
:intro-wizard/multiaccounts
|
||||
:intro-wizard/root-key
|
||||
:intro-wizard/passphrase
|
||||
:intro-wizard/passphrase-word-count
|
||||
:intro-wizard/derived
|
||||
:intro-wizard/next-button-disabled?]))
|
|
@ -131,7 +131,7 @@
|
|||
{:content-container-style {:justify-content :flex-start}}
|
||||
(for [[acc accessibility-n] (map vector multiaccounts (range (count multiaccounts)))]
|
||||
(let [selected? (= (:id acc) selected-id)
|
||||
public-key (get-in acc [:derived constants/path-whisper-keyword :publicKey])]
|
||||
public-key (get-in acc [:derived constants/path-whisper-keyword :public-key])]
|
||||
^{:key public-key}
|
||||
[react/touchable-highlight
|
||||
{:accessibility-label (keyword (str "select-account-button-" accessibility-n))
|
||||
|
|
|
@ -5,8 +5,12 @@
|
|||
(defn valid-public-key? [s]
|
||||
(boolean (re-matches #"0x04[0-9a-f]{128}" s)))
|
||||
|
||||
(defn valid-key-uid? [s]
|
||||
(boolean (re-matches #"0x[0-9a-f]{64}" s)))
|
||||
|
||||
(spec/def :global/not-empty-string (spec/and string? not-empty))
|
||||
(spec/def :global/public-key (spec/and :global/not-empty-string valid-public-key?))
|
||||
(spec/def :global/key-uid (spec/and :global/not-empty-string valid-key-uid?))
|
||||
(spec/def :global/address ethereum/address?)
|
||||
|
||||
(spec/def :status/tag (spec/and :global/not-empty-string
|
||||
|
|
|
@ -52,3 +52,17 @@
|
|||
(is (= (i18n/label :recovery-typo-dialog-title) (-> new-cofx :ui/show-confirmation :title)))
|
||||
(is (= (i18n/label :recovery-typo-dialog-description) (-> new-cofx :ui/show-confirmation :content)))
|
||||
(is (= (i18n/label :recovery-confirm-phrase) (-> new-cofx :ui/show-confirmation :confirm-button-text)))))
|
||||
|
||||
(deftest on-import-multiaccount-success
|
||||
(testing "importing a new multiaccount"
|
||||
(let [res (models/on-import-multiaccount-success
|
||||
{:db {:multiaccounts/multiaccounts {:acc1 {}}}}
|
||||
{:key-uid :acc2}
|
||||
nil)]
|
||||
(is (nil? (:utils/show-confirmation res)))))
|
||||
(testing "importing an existing multiaccount"
|
||||
(let [res (models/on-import-multiaccount-success
|
||||
{:db {:multiaccounts/multiaccounts {:acc1 {}}}}
|
||||
{:key-uid :acc1}
|
||||
nil)]
|
||||
(is (contains? res :utils/show-confirmation)))))
|
||||
|
|
Loading…
Reference in New Issue