chore: remove old wallet code, signing code and keycard code (#19467)
This commit is contained in:
parent
ce7912632c
commit
63a168b6f4
|
@ -1,131 +0,0 @@
|
|||
(ns legacy.status-im.bootnodes.core
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def address-regex #"enode://[a-zA-Z0-9]+:?(.*)\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
|
||||
|
||||
(defn valid-address?
|
||||
[address]
|
||||
(re-matches address-regex address))
|
||||
|
||||
(defn- build
|
||||
[id bootnode-name address chain]
|
||||
{:address address
|
||||
:chain chain
|
||||
:id (string/replace id "-" "")
|
||||
:name bootnode-name})
|
||||
|
||||
(rf/defn fetch
|
||||
[cofx id]
|
||||
(let [network (get-in cofx [:db :networks/current-network])]
|
||||
(get-in cofx [:db :profile/profile :custom-bootnodes network id])))
|
||||
|
||||
(rf/defn set-input
|
||||
{:events [:bootnodes.ui/input-changed]}
|
||||
[{:keys [db]} input-key value]
|
||||
{:db (update
|
||||
db
|
||||
:bootnodes/manage
|
||||
assoc
|
||||
input-key
|
||||
{:value value
|
||||
:error (case input-key
|
||||
:id false
|
||||
:name (string/blank? value)
|
||||
:url (not (valid-address? value)))})})
|
||||
|
||||
(rf/defn edit
|
||||
{:events [:bootnodes.ui/add-bootnode-pressed]}
|
||||
[{:keys [db] :as cofx} id]
|
||||
(let [{:keys [id
|
||||
address
|
||||
name]}
|
||||
(fetch cofx id)
|
||||
fxs (rf/merge cofx
|
||||
(set-input :id id)
|
||||
(set-input :url (str address))
|
||||
(set-input :name (str name)))]
|
||||
(assoc fxs :dispatch [:navigate-to :edit-bootnode])))
|
||||
|
||||
(defn custom-bootnodes-in-use?
|
||||
[{:keys [db]}]
|
||||
(let [network (:networks/current-network db)]
|
||||
(get-in db [:profile/profile :custom-bootnodes-enabled? network])))
|
||||
|
||||
(rf/defn delete
|
||||
[{{:profile/keys [profile] :as db} :db :as cofx} id]
|
||||
(let [network (:networks/current-network db)
|
||||
new-profile (update-in profile [:custom-bootnodes network] dissoc id)]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db :profile/profile new-profile)}
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:custom-bootnodes
|
||||
(:custom-bootnodes new-profile)
|
||||
{:success-event (when (custom-bootnodes-in-use? cofx)
|
||||
[:multiaccounts.update.callback/save-settings-success])}))))
|
||||
|
||||
(rf/defn upsert
|
||||
{:events [:bootnodes.ui/save-pressed]
|
||||
:interceptors [(re-frame/inject-cofx :random-id-generator)]}
|
||||
[{{:bootnodes/keys [manage] :profile/keys [profile] :as db} :db
|
||||
random-id-generator :random-id-generator
|
||||
:as cofx}]
|
||||
(let [{:keys [name id url]} manage
|
||||
network (:networks/current-network db)
|
||||
bootnode (build
|
||||
(or (:value id) (random-id-generator))
|
||||
(:value name)
|
||||
(:value url)
|
||||
network)
|
||||
new-bootnodes (assoc-in
|
||||
(:custom-bootnodes profile)
|
||||
[network (:id bootnode)]
|
||||
bootnode)]
|
||||
|
||||
(rf/merge cofx
|
||||
{:db (dissoc db :bootnodes/manage)
|
||||
:dispatch [:navigate-back]}
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:custom-bootnodes
|
||||
new-bootnodes
|
||||
{:success-event (when (custom-bootnodes-in-use? cofx)
|
||||
[:multiaccounts.update.callback/save-settings-success])}))))
|
||||
|
||||
(rf/defn toggle-custom-bootnodes
|
||||
{:events [:bootnodes.ui/custom-bootnodes-switch-toggled]}
|
||||
[{:keys [db] :as cofx} value]
|
||||
(let [current-network (:networks/current-network db)
|
||||
bootnodes-settings (get-in db [:profile/profile :custom-bootnodes-enabled?])]
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
:custom-bootnodes-enabled?
|
||||
(assoc bootnodes-settings current-network value)
|
||||
{:success-event [:multiaccounts.update.callback/save-settings-success]})))
|
||||
|
||||
(rf/defn set-bootnodes-from-qr
|
||||
{:events [:bootnodes.callback/qr-code-scanned]}
|
||||
[cofx url]
|
||||
(assoc (set-input cofx :url (string/trim url))
|
||||
:dispatch
|
||||
[:navigate-back]))
|
||||
|
||||
(rf/defn show-delete-bootnode-confirmation
|
||||
{:events [:bootnodes.ui/delete-pressed]}
|
||||
[_ bootnode-id]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/delete-bootnode-title)
|
||||
:content (i18n/label :t/delete-bootnode-are-you-sure)
|
||||
:confirm-button-text (i18n/label :t/delete-bootnode)
|
||||
:on-accept #(re-frame/dispatch [:bootnodes.ui/delete-confirmed
|
||||
bootnode-id])}})
|
||||
|
||||
(rf/defn delete-bootnode
|
||||
{:events [:bootnodes.ui/delete-confirmed]}
|
||||
[cofx bootnode-id]
|
||||
(rf/merge cofx
|
||||
(delete bootnode-id)
|
||||
(navigation/navigate-back)))
|
|
@ -1,180 +0,0 @@
|
|||
(ns legacy.status-im.bootnodes.core-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
[legacy.status-im.bootnodes.core :as model]))
|
||||
|
||||
(def bootnode-id
|
||||
"1da276e34126e93babf24ec88aac1a7602b4cbb2e11b0961d0ab5e989ca9c261aa7f7c1c85f15550a5f1e5a5ca2305b53b9280cf5894d5ecf7d257b173136d40")
|
||||
(def host "167.99.209.61:30504")
|
||||
|
||||
(def valid-bootnode-address (str "enode://" bootnode-id "@" host))
|
||||
|
||||
(deftest upsert-bootnode
|
||||
(testing "adding a new bootnode"
|
||||
(let [new-bootnode {:name {:value "name"}
|
||||
:url {:value "url"}}
|
||||
expected {"mainnet_rpc" {"someid" {:name "name"
|
||||
:address "url"
|
||||
:chain "mainnet_rpc"
|
||||
:id "someid"}}}
|
||||
actual (model/upsert
|
||||
{:random-id-generator (constantly "some-id")
|
||||
:db {:bootnodes/manage new-bootnode
|
||||
:networks/current-network "mainnet_rpc"
|
||||
:profile/profile {:not-empty
|
||||
"would throw an error if was empty"}}})]
|
||||
(is (= expected (get-in actual [:db :profile/profile :custom-bootnodes])))))
|
||||
(testing "adding an existing bootnode"
|
||||
(let [new-bootnode {:id {:value "a"}
|
||||
:name {:value "new-name"}
|
||||
:url {:value "new-url"}}
|
||||
expected {"mainnet_rpc" {"a" {:name "new-name"
|
||||
:address "new-url"
|
||||
:chain "mainnet_rpc"
|
||||
:id "a"}}}
|
||||
actual (model/upsert
|
||||
{:random-id-generator (constantly "some-id")
|
||||
:db {:bootnodes/manage new-bootnode
|
||||
:networks/current-network "mainnet_rpc"
|
||||
:profile/profile {:custom-bootnodes
|
||||
{"mainnet_rpc"
|
||||
{"a" {:name "name"
|
||||
:address "url"
|
||||
:chain "mainnet_rpc"
|
||||
:id "a"}}}}}})]
|
||||
(is (= expected (get-in actual [:db :profile/profile :custom-bootnodes]))))))
|
||||
|
||||
(deftest set-input-bootnode
|
||||
(testing "it validates names"
|
||||
(testing "correct name"
|
||||
(is (= {:db {:bootnodes/manage {:name {:value "value"
|
||||
:error false}}}}
|
||||
(model/set-input {:db {}} :name "value"))))
|
||||
(testing "blank name"
|
||||
(is (= {:db {:bootnodes/manage {:name {:value ""
|
||||
:error true}}}}
|
||||
(model/set-input {:db {}} :name "")))))
|
||||
(testing "it validates bootnode url"
|
||||
(testing "correct url"
|
||||
(is (= {:db {:bootnodes/manage {:url {:value valid-bootnode-address
|
||||
:error false}}}}
|
||||
(model/set-input {:db {}} :url valid-bootnode-address))))
|
||||
(testing "broken url"
|
||||
(is (= {:db {:bootnodes/manage {:url {:value "broken"
|
||||
:error true}}}}
|
||||
(model/set-input {:db {}} :url "broken"))))))
|
||||
|
||||
(deftest set-bootnode-from-qr
|
||||
(testing "correct name"
|
||||
(is (= {:dispatch [:navigate-back]
|
||||
:db {:bootnodes/manage {:url {:value valid-bootnode-address
|
||||
:error false}}}}
|
||||
(model/set-bootnodes-from-qr {:db {}} (str valid-bootnode-address " "))))))
|
||||
|
||||
(deftest edit-bootnode
|
||||
(let [db {:networks/current-network "mainnet_rpc"
|
||||
:profile/profile
|
||||
{:custom-bootnodes
|
||||
{"mainnet_rpc"
|
||||
{"a" {:id "a"
|
||||
:name "name"
|
||||
:address valid-bootnode-address}}}}}
|
||||
cofx {:db db}]
|
||||
(testing "when no id is given"
|
||||
(let [actual (model/edit cofx nil)]
|
||||
(testing "it resets :bootnodes/manage"
|
||||
(is (= {:id {:value nil
|
||||
:error false}
|
||||
:url {:value ""
|
||||
:error true}
|
||||
:name {:value ""
|
||||
:error true}}
|
||||
(-> actual :db :bootnodes/manage))))
|
||||
(testing "it navigates to edit-bootnode view"
|
||||
(is (= [:navigate-to :edit-bootnode]
|
||||
(-> actual :dispatch))))))
|
||||
(testing "when an id is given"
|
||||
(testing "when the bootnode is in the list"
|
||||
(let [actual (model/edit cofx "a")]
|
||||
(testing "it populates the fields with the correct values"
|
||||
(is (= {:id {:value "a"
|
||||
:error false}
|
||||
:url {:value valid-bootnode-address
|
||||
:error false}
|
||||
:name {:value "name"
|
||||
:error false}}
|
||||
(-> actual :db :bootnodes/manage))))
|
||||
(testing "it navigates to edit-bootnode view"
|
||||
(is (= [:navigate-to :edit-bootnode]
|
||||
(-> actual :dispatch))))))
|
||||
(testing "when the bootnode is not in the list"
|
||||
(let [actual (model/edit cofx "not-existing")]
|
||||
(testing "it populates the fields with the correct values"
|
||||
(is (= {:id {:value nil
|
||||
:error false}
|
||||
:url {:value ""
|
||||
:error true}
|
||||
:name {:value ""
|
||||
:error true}}
|
||||
(-> actual :db :bootnodes/manage))))
|
||||
(testing "it navigates to edit-bootnode view"
|
||||
(is (= [:navigate-to :edit-bootnode]
|
||||
(-> actual :dispatch)))))))))
|
||||
|
||||
(deftest fetch-bootnode
|
||||
(testing "it fetches the bootnode from the db"
|
||||
(let [cofx {:db {:networks/current-network "mainnet_rpc"
|
||||
:profile/profile {:custom-bootnodes
|
||||
{"mainnet_rpc"
|
||||
{"a" {:id "a"
|
||||
:name "name"
|
||||
:address
|
||||
"enode://old-id:old-password@url:port"}}}}}}]
|
||||
(is (model/fetch cofx "a")))))
|
||||
|
||||
(deftest custom-bootnodes-in-use?
|
||||
(testing "is on the same network"
|
||||
(testing "it returns false when not enabled"
|
||||
(is (not (model/custom-bootnodes-in-use? {:db {:networks/current-network "mainnet_rpc"}}))))
|
||||
(testing "it returns true when enabled"
|
||||
(is (model/custom-bootnodes-in-use?
|
||||
{:db {:networks/current-network "mainnet_rpc"
|
||||
:profile/profile {:custom-bootnodes-enabled?
|
||||
{"mainnet_rpc" true}}}}))))
|
||||
(testing "is on a different network"
|
||||
(testing "it returns false when not enabled"
|
||||
(is (not (model/custom-bootnodes-in-use? {:db {:networks/current-network "goerli_rpc"}}))))
|
||||
(testing "it returns true when enabled"
|
||||
(is (not (model/custom-bootnodes-in-use?
|
||||
{:db {:networks/current-network "goerli_rpc"
|
||||
:profile/profile {:custom-bootnodes-enabled?
|
||||
{"mainnnet_rpc" true}}}}))))))
|
||||
|
||||
(deftest delete-bootnode
|
||||
(testing "non existing bootnode"
|
||||
(let [cofx {:db {:networks/current-network "mainnet_rpc"
|
||||
:profile/profile {:custom-bootnodes
|
||||
{"mainnet_rpc"
|
||||
{"a" {:id "a"
|
||||
:name "name"
|
||||
:address
|
||||
"enode://old-id:old-password@url:port"}}}
|
||||
:custom-bootnodes-enabled?
|
||||
{"mainnnet_rpc" true}}}}
|
||||
actual (model/delete cofx "b")]
|
||||
(testing "it does not removes the bootnode"
|
||||
(is (model/fetch actual "a")))))
|
||||
(testing "existing bootnode"
|
||||
(let [cofx {:db {:networks/current-network "mainnet_rpc"
|
||||
:profile/profile {:custom-bootnodes
|
||||
{"mainnet_rpc"
|
||||
{"a" {:id "a"
|
||||
:name "name"
|
||||
:address
|
||||
"enode://old-id:old-password@url:port"}}}
|
||||
:custom-bootnodes-enabled?
|
||||
{"mainnnet_rpc" true}}}}
|
||||
actual (model/delete cofx "a")]
|
||||
|
||||
(testing "it removes the bootnode"
|
||||
(is (not (model/fetch actual "a")))))))
|
|
@ -3,12 +3,10 @@
|
|||
["eth-phishing-detect" :as eth-phishing-detect]
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
|
||||
[legacy.status-im.browser.eip3326 :as eip3326]
|
||||
[legacy.status-im.browser.permissions :as browser.permissions]
|
||||
[legacy.status-im.browser.webview-ref :as webview-ref]
|
||||
[legacy.status-im.ethereum.ens :as ens]
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[legacy.status-im.signing.core :as signing]
|
||||
[legacy.status-im.ui.components.list-selection :as list-selection]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[legacy.status-im.utils.random :as random]
|
||||
|
@ -393,64 +391,6 @@
|
|||
constants/web3-eth-sign constants/web3-keycard-sign-typed-data}
|
||||
method))
|
||||
|
||||
(rf/defn web3-send-async
|
||||
[cofx dapp-name {:keys [method params id] :as payload} message-id]
|
||||
(let [message? (web3-sign-message? method)
|
||||
dapps-address (get-in cofx [:db :profile/profile :dapps-address])
|
||||
typed? (and (not= constants/web3-personal-sign method)
|
||||
(not= constants/web3-eth-sign method))]
|
||||
(if (or message? (= constants/web3-send-transaction method))
|
||||
(let [[address data] (cond (and (= method constants/web3-keycard-sign-typed-data)
|
||||
(not (vector? params)))
|
||||
;; We don't use signer argument for keycard sign-typed-data
|
||||
["0x0" params]
|
||||
message? (normalize-sign-message-params params
|
||||
typed?)
|
||||
:else [nil nil])]
|
||||
(when (or (not message?) (and address data))
|
||||
(signing/sign cofx
|
||||
(merge
|
||||
(if message?
|
||||
{:message {:address address
|
||||
:data data
|
||||
:v4 (= constants/web3-sign-typed-data-v4 method)
|
||||
:typed? typed?
|
||||
:pinless? (= method constants/web3-keycard-sign-typed-data)
|
||||
:from dapps-address}}
|
||||
{:tx-obj (-> params
|
||||
first
|
||||
(update :from #(or % dapps-address))
|
||||
(dissoc :gasPrice))})
|
||||
{:on-result [:browser.dapp/transaction-on-result message-id id]
|
||||
:on-error [:browser.dapp/transaction-on-error message-id]}))))
|
||||
(cond
|
||||
(#{"eth_accounts" "eth_coinbase"} method)
|
||||
(send-to-bridge
|
||||
cofx
|
||||
{:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:result {:jsonrpc "2.0"
|
||||
:id (int id)
|
||||
:result (if (= method "eth_coinbase") dapps-address [dapps-address])}})
|
||||
(= method "personal_ecRecover")
|
||||
{:signing.fx/recover-message {:params {:message (first params)
|
||||
:signature (second params)}
|
||||
:on-completed #(re-frame/dispatch
|
||||
[:browser.callback/call-rpc
|
||||
{:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:result (types/json->clj %)}])}}
|
||||
(= method "wallet_switchEthereumChain")
|
||||
(eip3326/handle-switch-ethereum-chain cofx dapp-name id message-id (first params))
|
||||
|
||||
:else
|
||||
{:browser/call-rpc [payload
|
||||
#(re-frame/dispatch [:browser.callback/call-rpc
|
||||
{:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:error %1
|
||||
:result %2}])]}))))
|
||||
|
||||
(rf/defn handle-no-permissions
|
||||
[cofx {:keys [method id]} message-id]
|
||||
(if (= method "eth_accounts")
|
||||
|
@ -479,9 +419,8 @@
|
|||
|
||||
(rf/defn web3-send-async-read-only
|
||||
[{:keys [db] :as cofx} dapp-name {:keys [method] :as payload} message-id]
|
||||
(if (has-permissions? db dapp-name method)
|
||||
(handle-no-permissions cofx payload message-id)
|
||||
(web3-send-async cofx dapp-name payload message-id)))
|
||||
(when (has-permissions? db dapp-name method)
|
||||
(handle-no-permissions cofx payload message-id)))
|
||||
|
||||
(rf/defn handle-scanned-qr-code
|
||||
{:events [:browser.bridge.callback/qr-code-scanned]}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
;reference https://eips.ethereum.org/EIPS/eip-3085 EIP-3085: Wallet Add Ethereum Chain RPC Method
|
||||
;(`wallet_addEthereumChain`)
|
||||
(ns legacy.status-im.browser.eip3085
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn send-success-call-to-bridge
|
||||
{:events [:eip3085/send-success-call-to-bridge]}
|
||||
[_ id messageId]
|
||||
{:browser/send-to-bridge {:type constants/web3-send-async-callback
|
||||
:messageId messageId
|
||||
:result {:jsonrpc "2.0"
|
||||
:id (int id)
|
||||
:result nil}}})
|
||||
|
||||
(rf/defn allow-permission
|
||||
{:events [:eip3085.ui/dapp-permission-allowed]}
|
||||
[{:keys [db] :as cofx} message-id {:keys [new-networks id]}]
|
||||
{:db (assoc db :networks/networks new-networks)
|
||||
:json-rpc/call [{:method "settings_saveSetting"
|
||||
:params [:networks/networks (vals new-networks)]
|
||||
:on-success #(re-frame/dispatch [:eip3085/send-success-call-to-bridge cofx id
|
||||
message-id])
|
||||
:on-error #(log/error "failed to perform settings_saveSetting" %)}]
|
||||
:dispatch [:bottom-sheet/hide-old]})
|
||||
|
||||
(rf/defn deny-permission
|
||||
{:events [:eip3085.ui/dapp-permission-denied]}
|
||||
[_ message-id _]
|
||||
{:browser/send-to-bridge {:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:error {:code 4001
|
||||
:message "User rejected the request."}}
|
||||
:dispatch [:bottom-sheet/hide-old]})
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
;reference https://eips.ethereum.org/EIPS/eip-3326 EIP-3326: Wallet Switch Ethereum Chain RPC Method
|
||||
;(`wallet_switchEthereumChain`)
|
||||
(ns legacy.status-im.browser.eip3326
|
||||
(:require
|
||||
[legacy.status-im.ui.screens.browser.eip3326.sheet :as sheet]
|
||||
[status-im.constants :as constants]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn deny-permission
|
||||
{:events [:eip3326.ui/dapp-permission-denied]}
|
||||
[{:keys [db] :as cofx} message-id _]
|
||||
{:browser/send-to-bridge {:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:error {:code 4001
|
||||
:message "User rejected the request."}}
|
||||
:dispatch [:bottom-sheet/hide-old]})
|
||||
|
||||
(rf/defn handle-switch-ethereum-chain
|
||||
{:events [:eip3326/handle-switch-ethereum-chain]}
|
||||
[{:keys [db] :as cofx} dapp-name id message-id {:keys [chainId] :as params}]
|
||||
(let [target-chain-id (js/parseInt chainId 16)
|
||||
networks (vals (get-in db [:networks/networks]))
|
||||
exist-chain-ids (set (map chain/network->chain-id networks))
|
||||
current-chain-id (chain/chain-id db)]
|
||||
(if (exist-chain-ids target-chain-id)
|
||||
(if (= current-chain-id target-chain-id)
|
||||
{:browser/send-to-bridge {:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:result {:jsonrpc "2.0"
|
||||
:id (int id)
|
||||
:result nil}}}
|
||||
(let [target-network (first (filter #(= (chain/network->chain-id %1) target-chain-id)
|
||||
networks))
|
||||
target-network-id (:id target-network)
|
||||
current-network (chain/current-network db)
|
||||
network-from (:name current-network)
|
||||
network-to (:name target-network)
|
||||
params (assoc params
|
||||
:target-network-id target-network-id
|
||||
:network-from network-from
|
||||
:network-to network-to)]
|
||||
{:dispatch [:bottom-sheet/show-sheet-old
|
||||
{:content (fn []
|
||||
[sheet/permissions-panel dapp-name message-id params])}]}))
|
||||
{:browser/send-to-bridge {:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:error
|
||||
{:code 4902
|
||||
:message
|
||||
(str
|
||||
"Unrecognized chain ID: "
|
||||
target-chain-id
|
||||
". Try adding the chain using wallet_addEthereumChain first.")}}})))
|
||||
|
|
@ -2,18 +2,8 @@
|
|||
(:require
|
||||
[clojure.set :as set]
|
||||
[legacy.status-im.data-store.visibility-status-updates :as visibility-status-updates]
|
||||
[status-im.config :as config]
|
||||
[utils.ethereum.eip.eip55 :as eip55]))
|
||||
|
||||
(defn rpc->networks
|
||||
[networks]
|
||||
(reduce (fn [acc {:keys [id] :as network}]
|
||||
(assoc acc id network))
|
||||
{}
|
||||
(if (seq networks)
|
||||
networks
|
||||
config/default-networks)))
|
||||
|
||||
(defn rpc->visible-tokens
|
||||
[visible-tokens]
|
||||
(reduce-kv (fn [acc chain visible-tokens]
|
||||
|
@ -28,25 +18,14 @@
|
|||
{}
|
||||
pinned-mailservers))
|
||||
|
||||
(defn rpc->custom-bootnodes
|
||||
[custom-bootnodes]
|
||||
(reduce-kv (fn [acc chain custom-bootnodes]
|
||||
(assoc acc (name chain) custom-bootnodes))
|
||||
{}
|
||||
custom-bootnodes))
|
||||
|
||||
(defn rpc->settings
|
||||
[settings]
|
||||
(-> settings
|
||||
(update :dapps-address eip55/address->checksum)
|
||||
(update :address eip55/address->checksum)
|
||||
(update :networks/networks rpc->networks)
|
||||
(update :networks/current-network #(if (seq %) % config/default-network))
|
||||
(update :wallet-legacy/visible-tokens rpc->visible-tokens)
|
||||
(update :pinned-mailservers rpc->pinned-mailservers)
|
||||
(update :link-previews-enabled-sites set)
|
||||
(update :custom-bootnodes rpc->custom-bootnodes)
|
||||
(update :custom-bootnodes-enabled? rpc->custom-bootnodes)
|
||||
(update :currency keyword)
|
||||
(visibility-status-updates/<-rpc-settings)
|
||||
(set/rename-keys {:compressedKey :compressed-key
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
(:require
|
||||
clojure.set
|
||||
legacy.status-im.backup.core
|
||||
legacy.status-im.bootnodes.core
|
||||
legacy.status-im.browser.core
|
||||
legacy.status-im.browser.permissions
|
||||
legacy.status-im.chat.models.loading
|
||||
|
@ -13,7 +12,6 @@
|
|||
legacy.status-im.data-store.visibility-status-updates
|
||||
legacy.status-im.fleet.core
|
||||
legacy.status-im.group-chats.core
|
||||
[legacy.status-im.keycard.core :as keycard]
|
||||
legacy.status-im.log-level.core
|
||||
legacy.status-im.mailserver.constants
|
||||
[legacy.status-im.mailserver.core :as mailserver]
|
||||
|
@ -192,14 +190,7 @@
|
|||
|
||||
(not (get db :screens/was-focused-once?))
|
||||
{:db (assoc db :screens/was-focused-once? true)})
|
||||
#(case view-id
|
||||
:keycard-settings (keycard/settings-screen-did-load %)
|
||||
:reset-card (keycard/reset-card-screen-did-load %)
|
||||
:enter-pin-settings (keycard/enter-pin-screen-did-load %)
|
||||
:keycard-login-pin (keycard/login-pin-screen-did-load %)
|
||||
:keycard-authentication-method (keycard/authentication-method-screen-did-load %)
|
||||
:multiaccounts (keycard/multiaccounts-screen-did-load %)
|
||||
nil)))
|
||||
))
|
||||
|
||||
;;TODO :replace by named events
|
||||
(rf/defn set-event
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
(ns legacy.status-im.keycard.backup-key
|
||||
(:require
|
||||
[legacy.status-im.ethereum.mnemonic :as mnemonic]
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
[legacy.status-im.multiaccounts.recover.core :as multiaccounts.recover]
|
||||
[legacy.status-im.signing.core :as signing.core]
|
||||
[legacy.status-im.utils.utils :as utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn backup-card-pressed
|
||||
{:events [:keycard-settings.ui/backup-card-pressed]}
|
||||
[{:keys [db] :as cofx} backup-type]
|
||||
(log/debug "[keycard] start backup")
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :creating-backup?] backup-type))}
|
||||
(when (:profile/profile db)
|
||||
(navigation/navigate-to :my-profile nil))
|
||||
(navigation/navigate-to :seed-phrase nil)))
|
||||
|
||||
(rf/defn recovery-card-pressed
|
||||
{:events [:keycard-settings.ui/recovery-card-pressed]}
|
||||
[{:keys [db] :as cofx} show-warning]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
;setting pin-retry-counter is a workaround for the way the PIN view
|
||||
;decides if it should accept PUK or PIN
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] 3)
|
||||
(assoc-in [:keycard :factory-reset-card?] true)
|
||||
(dissoc :popover/popover))
|
||||
:hide-popover nil}
|
||||
(signing.core/discard)
|
||||
(if show-warning
|
||||
(utils/show-confirmation
|
||||
{:title (i18n/label :t/keycard-recover-title)
|
||||
:content (i18n/label :t/keycard-recover-text)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/no)
|
||||
:on-accept #(re-frame/dispatch [:keycard-settings.ui/backup-card-pressed
|
||||
:recovery-card])
|
||||
:on-cancel #()})
|
||||
(backup-card-pressed :recovery-card))))
|
||||
|
||||
(rf/defn start-keycard-backup
|
||||
{:events [::start-keycard-backup]}
|
||||
[{:keys [db] :as cofx}]
|
||||
{::multiaccounts.recover/import-multiaccount {:passphrase (-> db
|
||||
:profile/key-storage
|
||||
:seed-phrase
|
||||
mnemonic/sanitize-passphrase)
|
||||
:password nil
|
||||
:success-event ::create-backup-card}})
|
||||
|
||||
(rf/defn create-backup-card
|
||||
{:events [::create-backup-card]}
|
||||
[{:keys [db] :as cofx} root-data derived-data]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(update :intro-wizard
|
||||
assoc
|
||||
:root-key root-data
|
||||
:derived derived-data
|
||||
:recovering? true
|
||||
:selected-storage-type :advanced)
|
||||
(assoc-in [:keycard :flow] :recovery)
|
||||
(update :profile/key-storage dissoc :seed-phrase))
|
||||
:dismiss-keyboard nil}
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to :keycard-onboarding-intro nil)))
|
|
@ -1,565 +0,0 @@
|
|||
(ns legacy.status-im.keycard.card
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[keycard.keycard :as keycard]
|
||||
[keycard.real-keycard :as real-keycard]
|
||||
[legacy.status-im.keycard.simulated-keycard :as simulated-keycard]
|
||||
[legacy.status-im.node.core :as node]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.config :as config]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.transforms :as types]))
|
||||
|
||||
(defonce card
|
||||
(if config/keycard-test-menu-enabled?
|
||||
(simulated-keycard/SimulatedKeycard.)
|
||||
(real-keycard/RealKeycard.)))
|
||||
|
||||
(defn check-nfc-support
|
||||
[]
|
||||
(log/debug "[keycard] check-nfc-support")
|
||||
(keycard/check-nfc-support
|
||||
card
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response] check-nfc-support")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/check-nfc-support-success response]))}))
|
||||
|
||||
(defn check-nfc-enabled
|
||||
[]
|
||||
(log/debug "[keycard] check-nfc-enabled")
|
||||
(keycard/check-nfc-enabled
|
||||
card
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response] check-nfc-enabled")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/check-nfc-enabled-success response]))}))
|
||||
|
||||
(defn open-nfc-settings
|
||||
[]
|
||||
(log/debug "[keycard] open-nfc-settings")
|
||||
(keycard/open-nfc-settings card))
|
||||
|
||||
(defn remove-event-listener
|
||||
[event]
|
||||
(log/debug "[keycard] remove-event-listener")
|
||||
(keycard/remove-event-listener card event))
|
||||
|
||||
(defn on-card-disconnected
|
||||
[callback]
|
||||
(log/debug "[keycard] on-card-disconnected")
|
||||
(keycard/on-card-disconnected card callback))
|
||||
|
||||
(defn on-card-connected
|
||||
[callback]
|
||||
(log/debug "[keycard] on-card-connected")
|
||||
(keycard/on-card-connected card callback))
|
||||
|
||||
(defn remove-event-listeners
|
||||
[]
|
||||
(log/debug "[keycard] remove-event-listeners")
|
||||
(keycard/remove-event-listeners card))
|
||||
|
||||
(defn register-card-events
|
||||
[]
|
||||
(log/debug "[keycard] register-card-events")
|
||||
(keycard/register-card-events
|
||||
card
|
||||
{:on-card-connected
|
||||
#(re-frame/dispatch [:keycard.callback/on-card-connected])
|
||||
|
||||
:on-card-disconnected
|
||||
#(re-frame/dispatch [:keycard.callback/on-card-disconnected])
|
||||
|
||||
:on-nfc-user-cancelled
|
||||
#(re-frame/dispatch [:keycard.callback/on-nfc-user-cancelled])
|
||||
|
||||
:on-nfc-timeout
|
||||
#(re-frame/dispatch [:keycard.callback/on-nfc-timeout])
|
||||
|
||||
:on-nfc-enabled
|
||||
#(re-frame/dispatch [:keycard.callback/check-nfc-enabled-success true])
|
||||
|
||||
:on-nfc-disabled
|
||||
#(re-frame/dispatch [:keycard.callback/check-nfc-enabled-success false])}))
|
||||
|
||||
(defn- error-object->map
|
||||
[^js object]
|
||||
{:code (.-code object)
|
||||
:error (.-message object)})
|
||||
|
||||
(defn set-pairings
|
||||
[pairings]
|
||||
(log/debug "[keycard] open-nfc-settings")
|
||||
(keycard/set-pairings card {:pairings pairings}))
|
||||
|
||||
(defn get-application-info
|
||||
[{:keys [on-success] :as args}]
|
||||
(log/debug "[keycard] get-application-info")
|
||||
(keycard/get-application-info
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] get-application-info")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-get-application-info-success
|
||||
response on-success]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] get-application-info")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-get-application-info-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn factory-reset
|
||||
[{:keys [on-success] :as args}]
|
||||
(log/debug "[keycard] factory-reset")
|
||||
(keycard/factory-reset
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] get-application-info")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-get-application-info-success
|
||||
response on-success]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] get-application-info")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-get-application-info-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn install-applet
|
||||
[]
|
||||
(log/debug "[keycard] install-applet")
|
||||
(keycard/install-applet
|
||||
card
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] install-applet")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-install-applet-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] install-applet")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-install-applet-error
|
||||
(error-object->map response)]))}))
|
||||
|
||||
(defn init-card
|
||||
[pin]
|
||||
(log/debug "[keycard] init-card")
|
||||
(keycard/init-card
|
||||
card
|
||||
{:pin pin
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] init-card")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-init-card-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] init-card")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-init-card-error
|
||||
(error-object->map response)]))}))
|
||||
|
||||
(defn install-applet-and-init-card
|
||||
[pin]
|
||||
(log/debug "[keycard] install-applet-and-init-card")
|
||||
(keycard/install-applet-and-init-card
|
||||
card
|
||||
{:pin pin
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] install-applet-and-init-card")
|
||||
#(re-frame/dispatch
|
||||
[:keycard.callback/on-install-applet-and-init-card-success
|
||||
response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] install-applet-and-init-card")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-install-applet-and-init-card-error
|
||||
(error-object->map response)]))}))
|
||||
|
||||
(defn pair
|
||||
[args]
|
||||
(log/debug "[keycard] pair")
|
||||
(keycard/pair
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] pair")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-pair-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] pair")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-pair-error (error-object->map response)]))})))
|
||||
|
||||
(defn generate-and-load-key
|
||||
[args]
|
||||
(log/debug "[keycard] generate-and-load-key")
|
||||
(keycard/generate-and-load-key
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] generate-and-load-key")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-generate-and-load-key-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] generate-and-load-key")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-generate-and-load-key-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn unblock-pin
|
||||
[args]
|
||||
(log/debug "[keycard] unblock-pin")
|
||||
(keycard/unblock-pin
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] unblock-pin")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-unblock-pin-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] unblock-pin")
|
||||
(re-frame/dispatch [:keycard.callback/on-unblock-pin-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn verify-pin
|
||||
[args]
|
||||
(log/debug "[keycard] verify-pin")
|
||||
(keycard/verify-pin
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] verify-pin")
|
||||
(re-frame/dispatch [:keycard.callback/on-verify-pin-success
|
||||
response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] verify-pin")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-verify-pin-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn change-pin
|
||||
[args]
|
||||
(log/debug "[keycard] change-pin")
|
||||
(keycard/change-pin
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] change-pin")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-change-pin-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] change-pin")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-change-pin-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn change-puk
|
||||
[args]
|
||||
(log/debug "[keycard] change-puk")
|
||||
(keycard/change-puk
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] change-puk")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-change-puk-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] change-puk")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-change-pin-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn change-pairing
|
||||
[args]
|
||||
(log/debug "[keycard] change-pairing")
|
||||
(keycard/change-pairing
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] change-pairing")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-change-pairing-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] change-pairing")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-change-pin-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn unpair
|
||||
[args]
|
||||
(log/debug "[keycard] unpair")
|
||||
(keycard/unpair
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] unpair")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-unpair-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] unpair")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-unpair-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn delete
|
||||
[]
|
||||
(log/debug "[keycard] delete")
|
||||
(keycard/delete
|
||||
card
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] delete")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-delete-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] delete")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-delete-error
|
||||
(error-object->map response)]))}))
|
||||
|
||||
(defn remove-key
|
||||
[args]
|
||||
(log/debug "[keycard] remove-key")
|
||||
(keycard/remove-key
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] remove-key")
|
||||
(re-frame/dispatch [:keycard.callback/on-remove-key-success
|
||||
response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] remove-key")
|
||||
(re-frame/dispatch [:keycard.callback/on-remove-key-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn remove-key-with-unpair
|
||||
[args]
|
||||
(log/debug "[keycard] remove-key-with-unpair")
|
||||
(keycard/remove-key-with-unpair
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] remove-key-with-unpair")
|
||||
(re-frame/dispatch [:keycard.callback/on-remove-key-success
|
||||
response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] remove-key-with-unpair")
|
||||
(re-frame/dispatch [:keycard.callback/on-remove-key-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn export-key
|
||||
[args]
|
||||
(log/debug "[keycard] export-key")
|
||||
(keycard/export-key
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [_response]
|
||||
(log/debug "[keycard response succ] export-key")
|
||||
(js/alert "feature no longer supported"))
|
||||
:on-failure
|
||||
(fn [_response]
|
||||
(log/debug "[keycard response fail] export-key"))})))
|
||||
|
||||
(defn unpair-and-delete
|
||||
[args]
|
||||
(log/debug "[keycard] unpair-and-delete")
|
||||
(keycard/unpair
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] unpair-and-delete")
|
||||
(re-frame/dispatch [:keycard.callback/on-unpair-and-delete-success
|
||||
response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] unpair-and-delete")
|
||||
(re-frame/dispatch [:keycard.callback/on-unpair-and-delete-error
|
||||
(error-object->map response)]))})))
|
||||
|
||||
(defn import-keys
|
||||
[{:keys [on-success] :as args}]
|
||||
(log/debug "[keycard] import-keys")
|
||||
(keycard/import-keys
|
||||
card
|
||||
(assoc
|
||||
args
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] import-keys")
|
||||
(re-frame/dispatch
|
||||
[(or on-success :keycard.callback/on-generate-and-load-key-success)
|
||||
response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/warn "[keycard response fail] import-keys"
|
||||
(error-object->map response))
|
||||
(re-frame/dispatch [:keycard.callback/on-get-keys-error
|
||||
(error-object->map response)])))))
|
||||
|
||||
(defn get-keys
|
||||
[{:keys [on-success] :as args}]
|
||||
(log/debug "[keycard] get-keys")
|
||||
(keycard/get-keys
|
||||
card
|
||||
(assoc
|
||||
args
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] get-keys")
|
||||
(re-frame/dispatch
|
||||
[(or on-success :keycard.callback/on-get-keys-success)
|
||||
response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/warn "[keycard response fail] get-keys"
|
||||
(error-object->map response))
|
||||
(re-frame/dispatch [:keycard.callback/on-get-keys-error
|
||||
(error-object->map response)])))))
|
||||
|
||||
(defn sign
|
||||
[{:keys [on-success on-failure] :as args}]
|
||||
(log/debug "[keycard] sign")
|
||||
(keycard/sign
|
||||
card
|
||||
(merge
|
||||
args
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] sign")
|
||||
(if on-success
|
||||
(on-success response)
|
||||
(re-frame/dispatch [:keycard.callback/on-sign-success response])))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] sign")
|
||||
(if on-failure
|
||||
(on-failure response)
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-sign-error
|
||||
(error-object->map response)])))})))
|
||||
|
||||
(defn install-cash-applet
|
||||
[]
|
||||
(log/debug "[keycard] install-cash-applet")
|
||||
(keycard/install-cash-applet
|
||||
card
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] install-cash-applet")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-install-applet-success response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] install-cash-applet")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-install-applet-error
|
||||
(error-object->map response)]))}))
|
||||
|
||||
(defn sign-typed-data
|
||||
[{card-hash :hash}]
|
||||
(log/debug "[keycard] sign-typed-data")
|
||||
(keycard/sign-typed-data
|
||||
card
|
||||
{:hash card-hash
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] sign-typed-data")
|
||||
(re-frame/dispatch [:keycard.callback/on-sign-success
|
||||
response]))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/debug "[keycard response fail] sign-typed-data")
|
||||
(re-frame/dispatch
|
||||
[:keycard.callback/on-sign-error
|
||||
(error-object->map response)]))}))
|
||||
|
||||
(defn save-multiaccount-and-login
|
||||
[_])
|
||||
|
||||
(defn login
|
||||
[{:keys [key-uid multiaccount-data password] :as args}]
|
||||
(if config/keycard-test-menu-enabled?
|
||||
(native-module/login-with-config key-uid multiaccount-data password node/login-node-config)
|
||||
(native-module/login-with-keycard (assoc args :node-config {:ProcessBackedupMessages false}))))
|
||||
|
||||
(def account-password (native-module/sha3 "no password"))
|
||||
|
||||
(defn send-transaction-with-signature
|
||||
[{:keys [transaction signature on-completed]}]
|
||||
(if config/keycard-test-menu-enabled?
|
||||
(native-module/send-transaction transaction account-password on-completed)
|
||||
(native-module/send-transaction-with-signature transaction signature on-completed)))
|
||||
|
||||
(defn start-nfc
|
||||
[args]
|
||||
(keycard/start-nfc card args))
|
||||
|
||||
(defn stop-nfc
|
||||
[args]
|
||||
(keycard/stop-nfc card args))
|
||||
|
||||
(defn set-nfc-message
|
||||
[args]
|
||||
(keycard/set-nfc-message card args))
|
||||
|
||||
(defn delete-multiaccount-before-migration
|
||||
[{:keys [key-uid on-success on-error]}]
|
||||
(if config/keycard-test-menu-enabled?
|
||||
(on-success)
|
||||
(native-module/delete-multiaccount
|
||||
key-uid
|
||||
(fn [result]
|
||||
(let [{:keys [error]} (types/json->clj result)]
|
||||
(if-not (string/blank? error)
|
||||
(on-error error)
|
||||
(on-success)))))))
|
|
@ -1,216 +0,0 @@
|
|||
(ns legacy.status-im.keycard.change-pin
|
||||
(:require
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
[legacy.status-im.keycard.onboarding :as onboarding]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/defn change-credentials-pressed
|
||||
{:events [:keycard-settings.ui/change-credentials-pressed]}
|
||||
[{:keys [db] :as cofx} changing]
|
||||
(rf/merge cofx
|
||||
{:db
|
||||
(assoc-in db
|
||||
[:keycard :pin]
|
||||
{:enter-step :current
|
||||
:current []
|
||||
:puk []
|
||||
:original []
|
||||
:confirmation []
|
||||
:puk-original []
|
||||
:puk-confirmation []
|
||||
:status nil
|
||||
:error-label nil
|
||||
:on-verified (case changing
|
||||
:pin :keycard/proceed-to-change-pin
|
||||
:puk :keycard/proceed-to-change-puk
|
||||
:pairing :keycard/proceed-to-change-pairing)})}
|
||||
(common/navigate-to-enter-pin-screen)))
|
||||
|
||||
(rf/defn proceed-to-change-pin
|
||||
{:events [:keycard/proceed-to-change-pin]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :enter-step] :original)
|
||||
(assoc-in [:keycard :pin :status] nil))}
|
||||
(navigation/navigate-replace :enter-pin-settings nil)))
|
||||
|
||||
(rf/defn proceed-to-change-puk
|
||||
{:events [:keycard/proceed-to-change-puk]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :enter-step] :puk-original)
|
||||
(assoc-in [:keycard :pin :status] nil))}
|
||||
(navigation/navigate-replace :enter-pin-settings nil)))
|
||||
|
||||
(rf/defn proceed-to-change-pairing
|
||||
{:events [:keycard/proceed-to-change-pairing]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(navigation/navigate-replace cofx :change-pairing-code nil))
|
||||
|
||||
(rf/defn discard-pin-change
|
||||
{:events [::on-cancel]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
(common/clear-pin)
|
||||
(common/hide-connection-sheet)
|
||||
(if (get-in db [:keycard :pin :puk-restore?])
|
||||
(navigation/navigate-to :multiaccounts nil)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))))
|
||||
|
||||
(rf/defn change-pin
|
||||
{:events [:keycard/change-pin]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [setup-step (get-in db [:keycard :setup-step])]
|
||||
(log/debug "[keycard] change-pin"
|
||||
"setup-step"
|
||||
setup-step)
|
||||
(if (= setup-step :pin)
|
||||
(onboarding/load-preparing-screen cofx)
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:sheet-options {:on-cancel [::on-cancel]}
|
||||
:on-card-connected :keycard/change-pin
|
||||
:handler
|
||||
(fn [{:keys [db] :as cofx}]
|
||||
(let [new-pin (common/vector->string
|
||||
(get-in db [:keycard :pin :original]))
|
||||
current-pin (common/vector->string
|
||||
(get-in db [:keycard :pin :current]))]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :pin :status] :verifying)
|
||||
|
||||
:keycard/change-pin
|
||||
{:new-pin new-pin
|
||||
:current-pin current-pin}})))}))))
|
||||
|
||||
(rf/defn change-puk
|
||||
{:events [:keycard/change-puk]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:sheet-options {:on-cancel [::on-cancel]}
|
||||
:on-card-connected :keycard/change-puk
|
||||
:handler
|
||||
(fn [{:keys [db] :as cofx}]
|
||||
(let [puk (common/vector->string
|
||||
(get-in db [:keycard :pin :puk-original]))
|
||||
pin (common/vector->string
|
||||
(get-in db [:keycard :pin :current]))]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :pin :status] :verifying)
|
||||
:keycard/change-puk {:puk puk
|
||||
:pin pin}})))}))
|
||||
|
||||
(rf/defn change-pairing
|
||||
{:events [:keycard/change-pairing]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:sheet-options {:on-cancel [::on-cancel]}
|
||||
:on-card-connected :keycard/change-pairing
|
||||
:handler
|
||||
(fn [{:keys [db] :as cofx}]
|
||||
(let [pairing (get-in db [:keycard :pin :pairing-code])
|
||||
pin (common/vector->string
|
||||
(get-in db [:keycard :pin :current]))]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :pin :status] :verifying)
|
||||
:keycard/change-pairing {:pairing pairing
|
||||
:pin pin}})))}))
|
||||
|
||||
(rf/defn change-pairing-code
|
||||
{:events [:keycard/change-pairing-code]}
|
||||
[{:keys [db] :as cofx} pairing]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :pin :pairing-code] (security/unmask pairing))}
|
||||
(change-pairing)))
|
||||
|
||||
(rf/defn on-change-pin-success
|
||||
{:events [:keycard.callback/on-change-pin-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin (get-in db [:keycard :pin :original])
|
||||
puk-restore? (get-in db [:keycard :pin :puk-restore?])]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:login pin
|
||||
:confirmation []
|
||||
:error-label nil})
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/pin-changed)}}
|
||||
(common/hide-connection-sheet)
|
||||
(if puk-restore?
|
||||
(navigation/navigate-to :multiaccounts nil)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))
|
||||
(when (:profile/login db)
|
||||
(common/get-keys-from-keycard)))))
|
||||
|
||||
(rf/defn on-change-puk-success
|
||||
{:events [:keycard.callback/on-change-puk-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:puk-original []
|
||||
:puk-confirmation []
|
||||
:error-label nil})
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/puk-changed)}}
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
|
||||
|
||||
(rf/defn on-change-pairing-success
|
||||
{:events [:keycard.callback/on-change-pairing-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:pairing-code nil
|
||||
:error-label nil})
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/pairing-changed)}}
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
|
||||
|
||||
(rf/defn on-change-pin-error
|
||||
{:events [:keycard.callback/on-change-pin-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[keycard] change pin error" error)
|
||||
(let [tag-was-lost? (common/tag-lost? (:error error))
|
||||
pin-retries (common/pin-retries (:error error))]
|
||||
(rf/merge
|
||||
cofx
|
||||
(if tag-was-lost?
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(common/set-on-card-connected :keycard/change-pin))
|
||||
(if-not (nil? pin-retries)
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
|
||||
(update-in [:keycard :pin]
|
||||
assoc
|
||||
:status :error
|
||||
:enter-step :current
|
||||
:puk []
|
||||
:current []
|
||||
:original []
|
||||
:confirmation []
|
||||
:sign []
|
||||
:error-label :t/pin-mismatch))}
|
||||
(when (zero? pin-retries) (common/frozen-keycard-popup))
|
||||
(navigation/navigate-to :enter-pin-settings nil))
|
||||
(common/show-wrong-keycard-alert))))))
|
|
@ -1,560 +0,0 @@
|
|||
(ns legacy.status-im.keycard.common
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
|
||||
[legacy.status-im.keycard.nfc :as nfc]
|
||||
[legacy.status-im.popover.core :as popover]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[legacy.status-im.utils.keychain.core :as keychain]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def default-pin "000000")
|
||||
|
||||
(def pin-mismatch-error #"Unexpected error SW, 0x63C(\d+)|wrongPIN\(retryCounter: (\d+)\)")
|
||||
|
||||
(defn pin-retries
|
||||
[error]
|
||||
(when-let [matched-error (re-matches pin-mismatch-error error)]
|
||||
(js/parseInt (second (filter some? matched-error)))))
|
||||
|
||||
(rf/defn dispatch-event
|
||||
[_ event]
|
||||
{:dispatch-n [[event]]})
|
||||
|
||||
(defn vector->string
|
||||
"Converts numbers stored in vector into string,
|
||||
e.g. [1 2 3 4 5 6] -> \"123456\""
|
||||
[v]
|
||||
(apply str v))
|
||||
|
||||
(defn get-card-state
|
||||
[{:keys [has-master-key?
|
||||
applet-installed?
|
||||
initialized?
|
||||
free-pairing-slots
|
||||
paired?]}]
|
||||
(cond
|
||||
|
||||
(not applet-installed?)
|
||||
:blank
|
||||
|
||||
(not initialized?)
|
||||
:pre-init
|
||||
|
||||
(not has-master-key?)
|
||||
:init
|
||||
|
||||
has-master-key?
|
||||
:profile/profile
|
||||
|
||||
(and (not paired?)
|
||||
(zero? free-pairing-slots))
|
||||
:no-pairing-slots))
|
||||
|
||||
(defn tag-lost?
|
||||
[error]
|
||||
(or
|
||||
(= error "Tag was lost.")
|
||||
(= error "NFCError:100")
|
||||
(re-matches #".*NFCError:100.*" error)))
|
||||
|
||||
(defn find-multiaccount-by-keycard-instance-uid
|
||||
[db keycard-instance-uid]
|
||||
(when keycard-instance-uid
|
||||
(->> (:profile/profiles-overview db)
|
||||
vals
|
||||
(filter #(= keycard-instance-uid (:keycard-instance-uid %)))
|
||||
first)))
|
||||
|
||||
(defn find-multiaccount-by-key-uid
|
||||
[db key-uid]
|
||||
(when key-uid
|
||||
(->> (:profile/profiles-overview db)
|
||||
vals
|
||||
(filter #(= (address/normalized-hex key-uid) (:key-uid %)))
|
||||
first)))
|
||||
|
||||
(defn get-pairing
|
||||
([db]
|
||||
(get-pairing db (get-in db [:keycard :application-info :key-uid])))
|
||||
([db key-uid]
|
||||
(or
|
||||
(get-in db [:profile/profile :keycard-pairing])
|
||||
(get-in db [:keycard :secrets :pairing])
|
||||
(when key-uid
|
||||
(:keycard-pairing
|
||||
(find-multiaccount-by-key-uid db key-uid))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/set-nfc-supported
|
||||
(fn [supported?]
|
||||
(nfc/set-nfc-supported? supported?)))
|
||||
|
||||
(rf/defn listen-to-hardware-back-button
|
||||
[{:keys [db]}]
|
||||
(when-not (get-in db [:keycard :back-button-listener])
|
||||
{:keycard/listen-to-hardware-back-button nil}))
|
||||
|
||||
(rf/defn remove-listener-to-hardware-back-button
|
||||
[{:keys [db]}]
|
||||
(when-let [listener (get-in db [:keycard :back-button-listener])]
|
||||
{:keycard/remove-listener-to-hardware-back-button listener}))
|
||||
|
||||
(rf/defn set-on-card-connected
|
||||
[{:keys [db]} on-connect]
|
||||
(log/debug "[keycard] set-on-card-connected" on-connect)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :on-card-connected] on-connect)
|
||||
(assoc-in [:keycard :last-on-card-connected] nil))})
|
||||
|
||||
(rf/defn stash-on-card-connected
|
||||
[{:keys [db]}]
|
||||
(let [on-connect (get-in db [:keycard :on-card-connected])]
|
||||
(log/debug "[keycard] stash-on-card-connected" on-connect)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :last-on-card-connected] on-connect)
|
||||
(assoc-in [:keycard :on-card-connected] nil))}))
|
||||
|
||||
(rf/defn restore-on-card-connected
|
||||
[{:keys [db]}]
|
||||
(let [on-connect (or
|
||||
(get-in db [:keycard :on-card-connected])
|
||||
(get-in db [:keycard :last-on-card-connected]))]
|
||||
(log/debug "[keycard] restore-on-card-connected" on-connect)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :on-card-connected] on-connect)
|
||||
(assoc-in [:keycard :last-on-card-connect] nil))}))
|
||||
|
||||
(rf/defn clear-on-card-connected
|
||||
[{:keys [db]}]
|
||||
(log/debug "[keycard] clear-on-card-connected")
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :on-card-connected] nil)
|
||||
(assoc-in [:keycard :last-on-card-connected] nil))})
|
||||
|
||||
(rf/defn set-on-card-read
|
||||
[{:keys [db]} on-connect]
|
||||
(log/debug "[keycard] set-on-card-read" on-connect)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :on-card-read] on-connect)
|
||||
(assoc-in [:keycard :last-on-card-read] nil))})
|
||||
|
||||
(rf/defn stash-on-card-read
|
||||
[{:keys [db]}]
|
||||
(let [on-connect (get-in db [:keycard :on-card-read])]
|
||||
(log/debug "[keycard] stash-on-card-read" on-connect)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :last-on-card-read] on-connect)
|
||||
(assoc-in [:keycard :on-card-read] nil))}))
|
||||
|
||||
(rf/defn restore-on-card-read
|
||||
[{:keys [db]}]
|
||||
(let [on-connect (or
|
||||
(get-in db [:keycard :on-card-read])
|
||||
(get-in db [:keycard :last-on-card-read]))]
|
||||
(log/debug "[keycard] restore-on-card-read" on-connect)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :on-card-read] on-connect)
|
||||
(assoc-in [:keycard :last-on-card-connect] nil))}))
|
||||
|
||||
(rf/defn clear-on-card-read
|
||||
[{:keys [db]}]
|
||||
(log/debug "[keycard] clear-on-card-read")
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :on-card-read] nil)
|
||||
(assoc-in [:keycard :last-on-card-read] nil))})
|
||||
|
||||
(rf/defn show-connection-sheet-component
|
||||
[{:keys [db] :as cofx}
|
||||
{:keys [on-card-connected on-card-read handler]
|
||||
{:keys [on-cancel]
|
||||
:or {on-cancel [::cancel-sheet-confirm]}}
|
||||
:sheet-options}]
|
||||
(assert (keyword? on-card-connected))
|
||||
(assert (fn? handler))
|
||||
(let [connected? (get-in db [:keycard :card-connected?])]
|
||||
(log/debug "[keycard] show-sheet-with-connection-check"
|
||||
"card-connected?"
|
||||
connected?)
|
||||
(rf/merge
|
||||
cofx
|
||||
(bottom-sheet/show-bottom-sheet-old
|
||||
{:view {:transparent platform/ios?
|
||||
:show-handle? false
|
||||
:backdrop-dismiss? false
|
||||
:disable-drag? true
|
||||
:back-button-cancel false}})
|
||||
(when on-card-read
|
||||
(set-on-card-read on-card-read))
|
||||
(set-on-card-connected on-card-connected)
|
||||
(when connected?
|
||||
(stash-on-card-connected))
|
||||
(when connected?
|
||||
handler))))
|
||||
|
||||
(rf/defn show-connection-sheet
|
||||
[{:keys [db] :as cofx} args]
|
||||
(let [nfc-running? (get-in db [:keycard :nfc-running?])]
|
||||
(log/debug "show connection; already running?" nfc-running?)
|
||||
(if nfc-running?
|
||||
(show-connection-sheet-component cofx args)
|
||||
{:keycard/start-nfc-and-show-connection-sheet args})))
|
||||
|
||||
(rf/defn on-nfc-ready-for-sheet
|
||||
{:events [:keycard.callback/show-connection-sheet]}
|
||||
[cofx args]
|
||||
(log/debug "on-nfc-ready-for-sheet")
|
||||
(show-connection-sheet-component cofx args))
|
||||
|
||||
(rf/defn hide-connection-sheet-component
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :card-read-in-progress?] false)}
|
||||
(restore-on-card-connected)
|
||||
(restore-on-card-read)
|
||||
(bottom-sheet/hide-bottom-sheet-old)))
|
||||
|
||||
(rf/defn hide-connection-sheet
|
||||
[cofx]
|
||||
(log/debug "hide-connection-sheet")
|
||||
{:keycard/stop-nfc-and-hide-connection-sheet nil})
|
||||
|
||||
(rf/defn on-nfc-ready-to-close-sheet
|
||||
{:events [:keycard.callback/hide-connection-sheet]}
|
||||
[cofx]
|
||||
(log/debug "on-nfc-ready-to-close-sheet")
|
||||
(hide-connection-sheet-component cofx))
|
||||
|
||||
(rf/defn clear-pin
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:login (get-in db [:keycard :pin :original])
|
||||
:export-key []
|
||||
:sign []
|
||||
:puk []
|
||||
:current []
|
||||
:original []
|
||||
:confirmation []
|
||||
:error-label nil
|
||||
:on-verified (get-in db [:keycard :pin :on-verified])
|
||||
:on-verified-failure (get-in db [:keycard :pin :on-verified])})}))
|
||||
|
||||
(rf/defn cancel-sheet-confirm
|
||||
{:events [::cancel-sheet-confirm
|
||||
:keycard/back-button-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(when-not (get-in db [:keycard :card-connected?])
|
||||
(rf/merge cofx
|
||||
(hide-connection-sheet)
|
||||
(clear-pin))))
|
||||
|
||||
(rf/defn cancel-sheet
|
||||
{:events [::cancel-sheet]}
|
||||
[_]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/keycard-cancel-setup-title)
|
||||
:content (i18n/label :t/keycard-cancel-setup-text)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/no)
|
||||
:on-accept #(re-frame/dispatch [::cancel-sheet-confirm])
|
||||
:on-cancel #()}})
|
||||
|
||||
(rf/defn on-add-listener-to-hardware-back-button
|
||||
"Adds listener to hardware back button on Android.
|
||||
During keycard setup we show user a warning that setup will be cancelled
|
||||
when back button pressed. This prevents user from going back during setup
|
||||
flow as some of the actions changing keycard step could not be repeated."
|
||||
{:events [:keycard/add-listener-to-hardware-back-button]}
|
||||
[{:keys [db]} listener]
|
||||
{:db (assoc-in db [:keycard :back-button-listener] listener)})
|
||||
|
||||
(rf/defn show-wrong-keycard-alert
|
||||
[_]
|
||||
(log/debug "show-wrong-keycard-alert")
|
||||
{:effects.utils/show-popup {:title (i18n/label :t/wrong-card)
|
||||
:content (i18n/label :t/wrong-card-text)}})
|
||||
|
||||
(rf/defn unauthorized-operation
|
||||
[cofx]
|
||||
(rf/merge cofx
|
||||
{:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/keycard-unauthorized-operation)}}
|
||||
(clear-on-card-connected)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
|
||||
|
||||
(rf/defn navigate-to-enter-pin-screen
|
||||
{:events [:keycard/navigate-to-enter-pin-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :pin :current] [])}
|
||||
(navigation/navigate-to :enter-pin-settings nil)))
|
||||
|
||||
(defn- tag-lost-exception?
|
||||
[code error]
|
||||
(or
|
||||
(= code "android.nfc.TagLostException")
|
||||
(= error "Tag was lost.")
|
||||
(= error "NFCError:100")))
|
||||
|
||||
(rf/defn process-error
|
||||
[{:keys [db]} code error]
|
||||
(when-not (tag-lost-exception? code error)
|
||||
{:db (assoc-in db [:keycard :setup-step] :error)}))
|
||||
|
||||
(rf/defn get-keys-from-keycard
|
||||
[{:keys [db]}]
|
||||
(let [key-uid (get-in db [:profile/login :key-uid])
|
||||
pin (string/join (get-in db [:keycard :pin :login]))]
|
||||
(log/debug "[keycard] get-keys-from-keycard"
|
||||
", not empty pin:"
|
||||
(boolean (seq pin)))
|
||||
(when (seq pin)
|
||||
{:db (assoc-in db [:keycard :pin :status] :verifying)
|
||||
:keycard/get-keys {:pin pin}})))
|
||||
|
||||
(rf/defn on-get-keys-success
|
||||
{:events [:keycard.callback/on-get-keys-success]}
|
||||
[{:keys [db] :as cofx} data]
|
||||
(let [{:keys [key-uid encryption-public-key whisper-private-key]
|
||||
:as account-data}
|
||||
(js->clj data :keywordize-keys true)
|
||||
{:keys [name]} (get-in db [:profile/profiles-overview key-uid])
|
||||
key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
multiaccount-data (types/clj->json {:name name
|
||||
:key-uid key-uid})
|
||||
save-keys? (get-in db [:profile/login :save-password?])]
|
||||
(rf/merge cofx
|
||||
{:db
|
||||
(-> db
|
||||
(assoc-in [:keycard :pin :status] nil)
|
||||
(assoc-in [:keycard :pin :login] [])
|
||||
(update-in [:keycard :application-info]
|
||||
assoc
|
||||
:puk-retry-counter 5
|
||||
:pin-retry-counter 3)
|
||||
(assoc-in [:keycard :profile/profile]
|
||||
(update account-data :whisper-public-key address/normalized-hex))
|
||||
(assoc-in [:keycard :flow] nil)
|
||||
(update :profile/login assoc
|
||||
:password encryption-public-key
|
||||
:key-uid key-uid
|
||||
:name name))
|
||||
|
||||
:keycard/login-with-keycard {:multiaccount-data multiaccount-data
|
||||
:password encryption-public-key
|
||||
:chat-key whisper-private-key
|
||||
:key-uid key-uid}}
|
||||
(when save-keys?
|
||||
(keychain/save-keycard-keys key-uid encryption-public-key whisper-private-key))
|
||||
(clear-on-card-connected)
|
||||
(clear-on-card-read)
|
||||
(hide-connection-sheet))))
|
||||
|
||||
(rf/defn blocked-or-frozen-keycard-popup
|
||||
[{:keys [db] :as cofx} card-status]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :pin :status] card-status)}
|
||||
(hide-connection-sheet)
|
||||
; do not try to display the popover if it is already open or
|
||||
; we are in the login interface (which has a different handling)
|
||||
(when-not (or (:profile/login db) (:popover/popover db))
|
||||
(popover/show-popover {:view card-status}))))
|
||||
|
||||
(rf/defn blocked-keycard-popup
|
||||
[cofx]
|
||||
(blocked-or-frozen-keycard-popup cofx :blocked-card))
|
||||
|
||||
(rf/defn frozen-keycard-popup
|
||||
[cofx]
|
||||
(blocked-or-frozen-keycard-popup cofx :frozen-card))
|
||||
|
||||
(rf/defn on-get-keys-error
|
||||
{:events [:keycard.callback/on-get-keys-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[keycard] get keys error: " error)
|
||||
(let [tag-was-lost? (tag-lost? (:error error))
|
||||
key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
flow (get-in db [:keycard :flow])
|
||||
pin-retries-count (pin-retries (:error error))]
|
||||
(if tag-was-lost?
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(if-not (nil? pin-retries-count)
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
|
||||
(update-in [:keycard :pin]
|
||||
assoc
|
||||
:status :error
|
||||
:login []
|
||||
:import-multiaccount []
|
||||
:error-label :t/pin-mismatch))}
|
||||
(hide-connection-sheet)
|
||||
(when (zero? pin-retries-count) (frozen-keycard-popup)))
|
||||
(show-wrong-keycard-alert)))))
|
||||
|
||||
(rf/defn factory-reset
|
||||
{:events [:keycard/factory-reset]}
|
||||
[{:keys [db]} on-card-read]
|
||||
(log/debug "[keycard] factory-reset")
|
||||
{:db (update db :keycard dissoc :factory-reset-card?)
|
||||
:keycard/factory-reset {:on-success on-card-read}})
|
||||
|
||||
;; Get application info
|
||||
|
||||
(rf/defn update-pairings
|
||||
[{:keys [db]} instance-uid pairing]
|
||||
(let [paired-on (datetime/timestamp)
|
||||
pairings (-> (get-in db [:keycard :pairings])
|
||||
(assoc instance-uid {:pairing pairing :paired-on paired-on}))]
|
||||
{:keycard/persist-pairings pairings
|
||||
:db (assoc-in db [:keycard :pairings] pairings)}))
|
||||
|
||||
(rf/defn get-application-info
|
||||
{:events [:keycard/get-application-info]}
|
||||
[{:keys [db]} on-card-read]
|
||||
(log/debug "[keycard] get-application-info")
|
||||
{:keycard/get-application-info {:on-success on-card-read}})
|
||||
|
||||
(rf/defn on-get-application-info-success
|
||||
{:events [:keycard.callback/on-get-application-info-success]}
|
||||
[{:keys [db] :as cofx} info on-success]
|
||||
(let [{:keys [pin-retry-counter puk-retry-counter instance-uid new-pairing]} info
|
||||
view-id (:view-id db)
|
||||
{:keys [on-card-read]} (:keycard db)
|
||||
on-success' (or on-success
|
||||
on-card-read)
|
||||
enter-step (get-in db
|
||||
[:keycard :pin
|
||||
:enter-step])]
|
||||
(log/debug "[keycard] on-get-application-info-success"
|
||||
"on-success" on-success'
|
||||
"pin-retry-counter" pin-retry-counter
|
||||
"puk-retry-counter" puk-retry-counter)
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :enter-step] enter-step)
|
||||
(assoc-in [:keycard :application-info] info)
|
||||
(assoc-in [:keycard :application-info :applet-installed?] true)
|
||||
(assoc-in [:keycard :application-info-error] nil))}
|
||||
(stash-on-card-read)
|
||||
(when new-pairing
|
||||
(update-pairings instance-uid new-pairing))
|
||||
(when (and (zero? pin-retry-counter)
|
||||
(pos? puk-retry-counter)
|
||||
(not= enter-step :puk))
|
||||
(frozen-keycard-popup))
|
||||
(fn [{:keys [db] :as cofx}]
|
||||
(if (zero? puk-retry-counter)
|
||||
(blocked-keycard-popup cofx)
|
||||
(when on-success'
|
||||
(dispatch-event cofx on-success')))))))
|
||||
|
||||
(rf/defn on-get-application-info-error
|
||||
{:events [:keycard.callback/on-get-application-info-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(let [on-card-read (get-in db [:keycard :on-card-read])
|
||||
on-card-connected (get-in db [:keycard :on-card-connected])
|
||||
last-on-card-connected (get-in db [:keycard :last-on-card-connected])
|
||||
login? (= on-card-read :keycard/login-with-keycard)
|
||||
tag-was-lost? (tag-lost? (:error error))]
|
||||
(log/debug "[keycard] application info error"
|
||||
error
|
||||
on-card-connected
|
||||
last-on-card-connected)
|
||||
(when-not tag-was-lost?
|
||||
(if login?
|
||||
(rf/merge cofx
|
||||
(clear-on-card-read)
|
||||
(navigation/navigate-to :not-keycard nil))
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :application-info-error] error)}
|
||||
|
||||
(when (contains?
|
||||
#{last-on-card-connected on-card-connected}
|
||||
:keycard/prepare-to-sign)
|
||||
(show-wrong-keycard-alert))
|
||||
|
||||
(when on-card-read
|
||||
(dispatch-event on-card-read)))))))
|
||||
|
||||
(rf/defn on-card-connected
|
||||
{:events [::on-card-connected]}
|
||||
[{:keys [db] :as cofx} _]
|
||||
(let [instance-uid (get-in db [:keycard :application-info :instance-uid])
|
||||
key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
should-read-instance-uid? (nil? instance-uid)
|
||||
on-card-connected (get-in db [:keycard :on-card-connected])
|
||||
on-card-read (cond
|
||||
should-read-instance-uid? :keycard/get-application-info
|
||||
:else (get-in db [:keycard :on-card-read]))]
|
||||
(log/debug "[keycard] on-card-connected" on-card-connected
|
||||
"on-card-read" on-card-read)
|
||||
(when on-card-connected
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :card-read-in-progress?] (boolean on-card-read)))}
|
||||
(when on-card-connected
|
||||
(dispatch-event on-card-connected))
|
||||
(stash-on-card-connected)
|
||||
(when (and on-card-read
|
||||
(nil? on-card-connected))
|
||||
(get-application-info on-card-read))))))
|
||||
|
||||
(rf/defn on-card-disconnected
|
||||
{:events [::on-card-disconnected]}
|
||||
[{:keys [db] :as cofx} _]
|
||||
(log/debug "[keycard] card disconnected")
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :card-read-in-progress?] false))}
|
||||
(restore-on-card-connected)
|
||||
(restore-on-card-read)))
|
||||
|
||||
(defn keycard-multiaccount?
|
||||
[db]
|
||||
(boolean (get-in db [:profile/profile :keycard-pairing])))
|
||||
|
||||
(rf/defn verify-pin
|
||||
{:events [:keycard/verify-pin]}
|
||||
[{:keys [db] :as cofx} {:keys [pin-step on-card-connected on-failure on-success]}]
|
||||
(let [on-success (or on-success
|
||||
(get-in db [:keycard :pin :on-verified]))
|
||||
on-failure (or on-failure
|
||||
(get-in db [:keycard :pin :on-verified-failure]))
|
||||
pin-step (or pin-step
|
||||
(get-in db [:keycard :pin :step]))]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (update-in db
|
||||
[:keycard :pin]
|
||||
assoc
|
||||
:step pin-step
|
||||
:on-verified on-success
|
||||
:on-verified-failure on-failure)}
|
||||
(show-connection-sheet
|
||||
{:on-card-connected (or on-card-connected :keycard/verify-pin)
|
||||
:handler
|
||||
(fn [{:keys [db] :as cofx}]
|
||||
(let [pin (vector->string (get-in db [:keycard :pin pin-step]))]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :pin :status] :verifying)
|
||||
:keycard/verify-pin {:pin pin}})))}))))
|
||||
|
||||
(rf/defn navigete-to-keycard-settings
|
||||
{:events [::navigate-to-keycard-settings]}
|
||||
[cofx]
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))
|
|
@ -1,43 +0,0 @@
|
|||
(ns legacy.status-im.keycard.common-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
[legacy.status-im.keycard.common :as common]))
|
||||
|
||||
(deftest test-show-connection-sheet
|
||||
(testing "the card is not connected yet"
|
||||
(let [db {:keycard {:card-connected? false}}
|
||||
res (common/show-connection-sheet-component
|
||||
{:db db}
|
||||
{:on-card-connected :do-something
|
||||
:handler (fn [{:keys [db]}]
|
||||
{:db (assoc db :some-key :some-value)})})]
|
||||
(is (= :do-something
|
||||
(get-in res [:db :keycard :on-card-connected])))
|
||||
(is (nil? (get-in res [:db :some-key])))
|
||||
(is (true? (get-in res [:db :bottom-sheet/show?])))))
|
||||
(testing "the card is connected before the interaction"
|
||||
(let [db {:keycard {:card-connected? true}}
|
||||
res (common/show-connection-sheet-component
|
||||
{:db db}
|
||||
{:on-card-connected :do-something
|
||||
:handler (fn [{:keys [db]}]
|
||||
{:db (assoc db :some-key :some-value)})})]
|
||||
(is (nil? (get-in res [:db :keycard :on-card-connected])))
|
||||
(is (= :do-something
|
||||
(get-in res [:db :keycard :last-on-card-connected])))
|
||||
(is (= :some-value (get-in res [:db :some-key])))
|
||||
(is (true? (get-in res [:db :bottom-sheet/show?])))))
|
||||
(testing "on-card-connected is not specified"
|
||||
(is
|
||||
(thrown?
|
||||
js/Error
|
||||
(common/show-connection-sheet-component
|
||||
{:db {}}
|
||||
{:handler (fn [_])}))))
|
||||
(testing "handler is not specified"
|
||||
(is
|
||||
(thrown?
|
||||
js/Error
|
||||
(common/show-connection-sheet-component
|
||||
{:db {}}
|
||||
{:on-card-connected :do-something})))))
|
|
@ -1,688 +0,0 @@
|
|||
(ns legacy.status-im.keycard.core
|
||||
(:require
|
||||
legacy.status-im.keycard.backup-key
|
||||
[legacy.status-im.keycard.card :as card]
|
||||
[legacy.status-im.keycard.change-pin :as change-pin]
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
legacy.status-im.keycard.delete-key
|
||||
legacy.status-im.keycard.export-key
|
||||
[legacy.status-im.keycard.login :as login]
|
||||
[legacy.status-im.keycard.mnemonic :as mnemonic]
|
||||
[legacy.status-im.keycard.onboarding :as onboarding]
|
||||
[legacy.status-im.keycard.recovery :as recovery]
|
||||
[legacy.status-im.keycard.sign :as sign]
|
||||
legacy.status-im.keycard.unpair
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[re-frame.db]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn show-keycard-has-multiaccount-alert
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :setup-step] nil)
|
||||
:effects.utils/show-confirmation {:title nil
|
||||
:content (i18n/label
|
||||
:t/keycard-has-multiaccount-on-it)
|
||||
:cancel-button-text ""
|
||||
:confirm-button-text :t/okay}}))
|
||||
|
||||
(rf/defn load-pin-screen
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] :pin)
|
||||
(assoc-in [:keycard :pin]
|
||||
{:enter-step :original
|
||||
:original []
|
||||
:confirmation []}))}
|
||||
(navigation/navigate-to :keycard-onboarding-pin nil)))
|
||||
|
||||
(rf/defn load-recovery-pin-screen
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin]
|
||||
{:enter-step :import-multiaccount
|
||||
:import-multiaccount []
|
||||
:current []}))}
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-replace :keycard-recovery-pin nil)))
|
||||
|
||||
(rf/defn load-pairing
|
||||
[{:keys [db]}]
|
||||
(let [instance-uid (get-in db [:keycard :application-info :instance-uid])
|
||||
pairing-data (or (get-in db [:keycard :pairings (keyword instance-uid)])
|
||||
(get-in db [:keycard :pairings instance-uid]))]
|
||||
{:db (update-in db [:keycard :secrets] merge pairing-data)}))
|
||||
|
||||
(rf/defn proceed-setup-with-initialized-card
|
||||
[{:keys [db] :as cofx} flow instance-uid paired?]
|
||||
(log/debug "[keycard] proceed-setup-with-initialized-card"
|
||||
"instance-uid"
|
||||
instance-uid)
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to cofx :keycard-recovery-no-key nil)
|
||||
(if paired?
|
||||
(rf/merge cofx
|
||||
(common/listen-to-hardware-back-button)
|
||||
(when (= flow :create)
|
||||
(mnemonic/set-mnemonic))
|
||||
(when (= flow :recovery)
|
||||
(onboarding/proceed-with-generating-key)))
|
||||
(if (get-in db [:keycard :secrets :password])
|
||||
(onboarding/load-pairing-screen cofx)
|
||||
(recovery/load-pair-screen cofx)))))
|
||||
|
||||
(rf/defn navigate-to-keycard-settings
|
||||
{:events [:profile.ui/keycard-settings-button-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :on-verified] nil)
|
||||
(assoc-in [:keycard :setup-step] nil))}
|
||||
(common/clear-on-card-connected)
|
||||
(navigation/navigate-to :keycard-settings nil)))
|
||||
|
||||
(rf/defn password-option-pressed
|
||||
{:eevents [:keycard.ui/password-option-pressed]}
|
||||
[{:keys [db]}]
|
||||
(when (= (get-in db [:keycard :flow]) :create)
|
||||
#())) ;;TODO with v1 flow
|
||||
|
||||
(rf/defn settings-screen-did-load
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :on-verified] nil)
|
||||
(assoc-in [:keycard :setup-step] nil))}
|
||||
(common/clear-on-card-connected)))
|
||||
|
||||
(defn reset-card-screen-did-load
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :reset-card :disabled?] false)})
|
||||
|
||||
(defn enter-pin-screen-did-load
|
||||
[{:keys [db]}]
|
||||
(let [enter-step (get-in db [:keycard :pin :enter-step])]
|
||||
{:db (assoc-in db [:keycard :pin enter-step] [])}))
|
||||
|
||||
(defn login-pin-screen-did-load
|
||||
[{:keys [db]}]
|
||||
(let [enter-step (get-in db [:keycard :pin :enter-step])]
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin enter-step] [])
|
||||
(dissoc :intro-wizard :recovered-account?))}))
|
||||
|
||||
(defn multiaccounts-screen-did-load
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :setup-step] nil)})
|
||||
|
||||
(defn authentication-method-screen-did-load
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :setup-step] nil)})
|
||||
|
||||
(rf/defn set-nfc-supported
|
||||
{:events [:keycard.callback/check-nfc-support-success]}
|
||||
[_ supported?]
|
||||
{:keycard/set-nfc-supported supported?})
|
||||
|
||||
;; TODO: Should be listener and replace the view in bottom sheet to avoid this
|
||||
(rf/defn on-check-nfc-enabled-success
|
||||
{:events [:keycard.callback/check-nfc-enabled-success]}
|
||||
[{:keys [db]} nfc-enabled?]
|
||||
(log/debug "[keycard] check-nfc-enabled-success"
|
||||
"nfc-enabled?"
|
||||
nfc-enabled?)
|
||||
{:db (assoc-in db [:keycard :nfc-enabled?] nfc-enabled?)})
|
||||
|
||||
(defn- proceed-to-pin-confirmation
|
||||
[fx]
|
||||
(assoc-in fx [:db :keycard :pin :enter-step] :confirmation))
|
||||
|
||||
(defn- proceed-to-change-puk-confirmation
|
||||
[fx]
|
||||
(assoc-in fx [:db :keycard :pin :enter-step] :puk-confirmation))
|
||||
|
||||
(defn- proceed-to-pin-reset-confirmation
|
||||
[fx]
|
||||
(-> fx
|
||||
(update-in [:db :keycard :pin] dissoc :reset-confirmation)
|
||||
(assoc-in [:db :keycard :pin :enter-step] :reset-confirmation)))
|
||||
|
||||
(defn- proceed-to-puk-confirmation
|
||||
[fx]
|
||||
(assoc-in fx [:db :keycard :pin :enter-step] :puk))
|
||||
|
||||
(rf/defn on-unblock-pin-success
|
||||
{:events [:keycard.callback/on-unblock-pin-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [reset-pin (get-in db [:keycard :pin :reset])]
|
||||
(rf/merge cofx
|
||||
{:db
|
||||
(-> db
|
||||
(update-in [:keycard :application-info]
|
||||
assoc
|
||||
:puk-retry-counter 5
|
||||
:pin-retry-counter 3)
|
||||
(update-in [:keycard :pin]
|
||||
assoc
|
||||
:status :after-unblocking
|
||||
:enter-step :login
|
||||
:login reset-pin
|
||||
:confirmation []
|
||||
:puk []
|
||||
:puk-restore? true
|
||||
:error-label nil))}
|
||||
(common/hide-connection-sheet)
|
||||
(common/clear-on-card-connected)
|
||||
(common/clear-on-card-read))))
|
||||
|
||||
(rf/defn on-unblock-pin-error
|
||||
{:events [:keycard.callback/on-unblock-pin-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(let [tag-was-lost? (common/tag-lost? (:error error))
|
||||
puk-retries (common/pin-retries (:error error))]
|
||||
(log/debug "[keycard] unblock pin error" error)
|
||||
(when-not tag-was-lost?
|
||||
(rf/merge cofx
|
||||
{:db
|
||||
(-> db
|
||||
(assoc-in [:keycard :application-info :puk-retry-counter] puk-retries)
|
||||
(update-in [:keycard :pin]
|
||||
merge
|
||||
{:status (if (zero? puk-retries) :blocked-card :error)
|
||||
:error-label :t/puk-mismatch
|
||||
:enter-step :puk
|
||||
:puk []}))}
|
||||
|
||||
(common/hide-connection-sheet)))))
|
||||
|
||||
(rf/defn clear-on-verify-handlers
|
||||
[{:keys [db]}]
|
||||
{:db (update-in db
|
||||
[:keycard :pin]
|
||||
dissoc
|
||||
:on-verified-failure
|
||||
:on-verified)})
|
||||
|
||||
(rf/defn on-verify-pin-success
|
||||
{:events [:keycard.callback/on-verify-pin-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [on-verified (get-in db [:keycard :pin :on-verified])]
|
||||
(log/debug "[hardwaller] success pin verification. on-verified" on-verified)
|
||||
(rf/merge cofx
|
||||
{:db (update-in db
|
||||
[:keycard :pin]
|
||||
merge
|
||||
{:status nil
|
||||
:error-label nil})}
|
||||
(common/clear-on-card-connected)
|
||||
(common/clear-on-card-read)
|
||||
;; TODO(Ferossgp): Each pin input should handle this event on it's own,
|
||||
;; now for simplicity do not hide bottom sheet when generating key
|
||||
;; and exporting key but should be refactored.
|
||||
(when-not (contains? #{:keycard/generate-and-load-key
|
||||
:wallet-legacy.accounts/generate-new-keycard-account
|
||||
:keycard/remove-key-with-unpair
|
||||
:keycard/unpair-and-delete}
|
||||
on-verified)
|
||||
(common/hide-connection-sheet))
|
||||
(when-not (contains? #{:keycard/unpair
|
||||
:keycard/generate-and-load-key
|
||||
:keycard/remove-key-with-unpair
|
||||
:keycard/unpair-and-delete
|
||||
:wallet-legacy.accounts/generate-new-keycard-account}
|
||||
on-verified)
|
||||
(common/get-application-info nil))
|
||||
(when on-verified
|
||||
(common/dispatch-event on-verified))
|
||||
(clear-on-verify-handlers))))
|
||||
|
||||
(rf/defn on-verify-pin-error
|
||||
{:events [:keycard.callback/on-verify-pin-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(let [tag-was-lost? (common/tag-lost? (:error error))
|
||||
setup? (boolean (get-in db [:keycard :setup-step]))
|
||||
on-verified-failure (get-in db [:keycard :pin :on-verified-failure])
|
||||
exporting? (get-in db [:keycard :on-export-success])
|
||||
pin-retries (common/pin-retries (:error error))]
|
||||
(log/debug "[keycard] verify pin error" error)
|
||||
(when-not tag-was-lost?
|
||||
(if-not (nil? pin-retries)
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
|
||||
(update-in [:keycard :pin]
|
||||
assoc
|
||||
:status :error
|
||||
:enter-step :current
|
||||
:puk []
|
||||
:current []
|
||||
:original []
|
||||
:confirmation []
|
||||
:sign []
|
||||
:error-label :t/pin-mismatch))}
|
||||
(common/hide-connection-sheet)
|
||||
(when (and (not setup?)
|
||||
(not on-verified-failure))
|
||||
(when exporting?
|
||||
(navigation/navigate-back)))
|
||||
;(navigation/navigate-to :enter-pin-settings nil)))
|
||||
(when (zero? pin-retries) (common/frozen-keycard-popup))
|
||||
(when on-verified-failure
|
||||
(fn [_]
|
||||
{:utils/dispatch-later
|
||||
[{:dispatch [on-verified-failure]
|
||||
:ms 200}]}))
|
||||
#_(clear-on-verify-handlers))
|
||||
|
||||
(rf/merge cofx
|
||||
(common/hide-connection-sheet)
|
||||
(common/show-wrong-keycard-alert)
|
||||
(clear-on-verify-handlers))))))
|
||||
|
||||
(rf/defn unblock-pin
|
||||
{:events [:keycard/unblock-pin]}
|
||||
[cofx]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:on-card-connected :keycard/unblock-pin
|
||||
:handler
|
||||
(fn [{:keys [db]}]
|
||||
(let [puk (common/vector->string (get-in db [:keycard :pin :puk]))
|
||||
pin (common/vector->string (get-in db [:keycard :pin :reset]))
|
||||
key-uid (get-in db [:keycard :application-info :key-uid])]
|
||||
{:db (assoc-in db [:keycard :pin :status] :verifying)
|
||||
:keycard/unblock-pin
|
||||
{:puk puk
|
||||
:new-pin pin}}))}))
|
||||
|
||||
(def pin-code-length 6)
|
||||
(def puk-code-length 12)
|
||||
|
||||
(rf/defn handle-pin-input
|
||||
[{:keys [db]} enter-step]
|
||||
(let [numbers-entered (count (get-in db [:keycard :pin enter-step]))]
|
||||
(when (or (= numbers-entered pin-code-length)
|
||||
(= numbers-entered puk-code-length))
|
||||
{:dispatch [:keycard/process-pin-input]})))
|
||||
|
||||
(rf/defn update-pin
|
||||
{:events [:keycard.ui/pin-numpad-button-pressed]}
|
||||
[{:keys [db] :as cofx} number enter-step]
|
||||
(log/debug "update-pin" enter-step)
|
||||
(let [numbers-entered (count (get-in db [:keycard :pin enter-step]))
|
||||
need-update? (if (or (= enter-step :puk)
|
||||
(= enter-step :puk-original)
|
||||
(= enter-step :puk-confirmation))
|
||||
(< numbers-entered puk-code-length)
|
||||
(< numbers-entered pin-code-length))]
|
||||
(rf/merge cofx
|
||||
{:db (cond-> (-> db
|
||||
(assoc-in [:keycard :pin :enter-step] enter-step)
|
||||
(assoc-in [:keycard :pin :status] nil))
|
||||
need-update? (update-in [:keycard :pin enter-step] (fnil conj []) number))}
|
||||
(when need-update?
|
||||
(handle-pin-input enter-step)))))
|
||||
|
||||
(defn- pin-enter-error
|
||||
[fx error-label]
|
||||
(update-in fx
|
||||
[:db :keycard :pin]
|
||||
merge
|
||||
{:status :error
|
||||
:error-label error-label
|
||||
:enter-step :original
|
||||
:original []
|
||||
:confirmation []}))
|
||||
|
||||
(defn- puk-enter-error
|
||||
[fx error-label]
|
||||
(update-in fx
|
||||
[:db :keycard :pin]
|
||||
merge
|
||||
{:status :error
|
||||
:error-label error-label
|
||||
:enter-step :puk-original
|
||||
:puk-original []
|
||||
:puk-confirmation []}))
|
||||
|
||||
(defn- pin-reset-error
|
||||
[fx error-label]
|
||||
(update-in fx
|
||||
[:db :keycard :pin]
|
||||
merge
|
||||
{:status :error
|
||||
:error-label error-label
|
||||
:enter-step :reset
|
||||
:reset []
|
||||
:reset-confirmation []}))
|
||||
|
||||
; PIN enter steps:
|
||||
; login - PIN is used to login
|
||||
; sign - PIN for transaction sign
|
||||
; current - current PIN to perform actions which require PIN auth
|
||||
; original - new PIN when user changes it or creates new one
|
||||
; confirmation - confirmation for new PIN
|
||||
(rf/defn process-pin-input
|
||||
{:events [:keycard/process-pin-input]}
|
||||
[{:keys [db]}]
|
||||
(let [enter-step (get-in db [:keycard :pin :enter-step])
|
||||
pin (get-in db [:keycard :pin enter-step])
|
||||
numbers-entered (count pin)]
|
||||
(log/debug "[keycard] process-pin-input"
|
||||
"enter-step" enter-step
|
||||
"numbers-entered" numbers-entered)
|
||||
(cond-> {:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
|
||||
(and (= enter-step :login)
|
||||
(= 6 numbers-entered))
|
||||
(login/proceed-to-login)
|
||||
|
||||
(and (= enter-step :original)
|
||||
(= pin-code-length numbers-entered))
|
||||
(proceed-to-pin-confirmation)
|
||||
|
||||
(and (= enter-step :original)
|
||||
(= pin-code-length numbers-entered)
|
||||
(= common/default-pin (common/vector->string pin)))
|
||||
(pin-enter-error :t/cannot-use-default-pin)
|
||||
|
||||
(and (= enter-step :import-multiaccount)
|
||||
(= pin-code-length numbers-entered))
|
||||
(recovery/load-recovering-key-screen)
|
||||
|
||||
(and (= enter-step :current)
|
||||
(= pin-code-length numbers-entered))
|
||||
(common/verify-pin {:pin-step :current})
|
||||
|
||||
(and (= enter-step :sign)
|
||||
(= pin-code-length numbers-entered))
|
||||
(sign/prepare-to-sign)
|
||||
|
||||
(and (= enter-step :puk)
|
||||
(= puk-code-length numbers-entered))
|
||||
(unblock-pin)
|
||||
|
||||
(and (= enter-step :confirmation)
|
||||
(= (get-in db [:keycard :pin :original])
|
||||
(get-in db [:keycard :pin :confirmation])))
|
||||
(change-pin/change-pin)
|
||||
|
||||
(and (= enter-step :confirmation)
|
||||
(= pin-code-length numbers-entered)
|
||||
(not= (get-in db [:keycard :pin :original])
|
||||
(get-in db [:keycard :pin :confirmation])))
|
||||
(pin-enter-error :t/pin-mismatch)
|
||||
|
||||
(and (= enter-step :puk-original)
|
||||
(= puk-code-length numbers-entered))
|
||||
(proceed-to-change-puk-confirmation)
|
||||
|
||||
(and (= enter-step :puk-confirmation)
|
||||
(= (get-in db [:keycard :pin :puk-original])
|
||||
(get-in db [:keycard :pin :puk-confirmation])))
|
||||
(change-pin/change-puk)
|
||||
|
||||
(and (= enter-step :puk-confirmation)
|
||||
(= puk-code-length numbers-entered)
|
||||
(not= (get-in db [:keycard :pin :puk-original])
|
||||
(get-in db [:keycard :pin :puk-confirmation])))
|
||||
(puk-enter-error :t/puk-mismatch)
|
||||
|
||||
(= enter-step :reset)
|
||||
(proceed-to-pin-reset-confirmation)
|
||||
|
||||
(and (= enter-step :reset-confirmation)
|
||||
(= (get-in db [:keycard :pin :reset])
|
||||
(get-in db [:keycard :pin :reset-confirmation])))
|
||||
(proceed-to-puk-confirmation)
|
||||
|
||||
(and (= enter-step :reset-confirmation)
|
||||
(= pin-code-length numbers-entered)
|
||||
(not= (get-in db [:keycard :pin :reset])
|
||||
(get-in db [:keycard :pin :reset-confirmation])))
|
||||
(pin-reset-error :t/pin-mismatch))))
|
||||
|
||||
(rf/defn set-multiaccount-pairing
|
||||
[cofx _ pairing paired-on]
|
||||
(rf/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:keycard-pairing
|
||||
pairing
|
||||
{})
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:keycard-paired-on
|
||||
paired-on
|
||||
{})))
|
||||
|
||||
(rf/defn on-retrieve-pairings-success
|
||||
{:events [:keycard.callback/on-retrieve-pairings-success]}
|
||||
[{:keys [db]} pairings]
|
||||
(card/set-pairings pairings)
|
||||
{:db (assoc-in db [:keycard :pairings] pairings)})
|
||||
|
||||
;; When pairing to device has completed, we need to persist pairing data to
|
||||
;; local storage. That's needed to ensure that during keycard setup
|
||||
;; keycard won't run out of pairings slots, ie. we don't pair the same
|
||||
;; card to the same device more than one time. Also, this allows the user to proceed
|
||||
;; with setup and skip the pairing step if the pairing was already done during a previous
|
||||
;; unfinished setup.
|
||||
|
||||
(rf/defn on-pair-success
|
||||
{:events [:keycard.callback/on-pair-success]}
|
||||
[{:keys [db] :as cofx} pairing]
|
||||
(let [setup-step (get-in db [:keycard :setup-step])
|
||||
flow (get-in db [:keycard :flow])
|
||||
instance-uid (get-in db [:keycard :application-info :instance-uid])
|
||||
multiaccount (common/find-multiaccount-by-keycard-instance-uid db instance-uid)
|
||||
paired-on (datetime/timestamp)
|
||||
pairings (-> (get-in db [:keycard :pairings])
|
||||
(dissoc (keyword instance-uid))
|
||||
(assoc instance-uid {:pairing pairing :paired-on paired-on}))
|
||||
next-step (if (= setup-step :pair)
|
||||
:begin
|
||||
:card-ready)]
|
||||
(rf/merge cofx
|
||||
{:keycard/persist-pairings pairings
|
||||
:db (-> db
|
||||
(assoc-in [:keycard :pairings] pairings)
|
||||
(assoc-in [:keycard :application-info :paired?] true)
|
||||
(assoc-in [:keycard :setup-step] next-step)
|
||||
(assoc-in [:keycard :secrets :pairing] pairing)
|
||||
(assoc-in [:keycard :secrets :paired-on] paired-on))}
|
||||
(when-not (and (= flow :recovery) (= next-step :card-ready))
|
||||
(common/hide-connection-sheet))
|
||||
(when multiaccount
|
||||
(set-multiaccount-pairing multiaccount pairing paired-on))
|
||||
(when (= flow :login)
|
||||
(navigation/navigate-to :multiaccounts nil))
|
||||
(when (= flow :recovery)
|
||||
(onboarding/proceed-with-generating-key))
|
||||
(when (= flow :import)
|
||||
(load-recovery-pin-screen))
|
||||
;; TODO: If card is already initialized need to confirm pin only then go to mnenmonic
|
||||
;; https://github.com/status-im/status-mobile/issues/9451
|
||||
(when (= flow :create)
|
||||
(mnemonic/set-mnemonic)))))
|
||||
|
||||
(rf/defn on-pair-error
|
||||
{:events [:keycard.callback/on-pair-error]}
|
||||
[{:keys [db] :as cofx} {:keys [error code]}]
|
||||
(log/debug "[keycard] pair error: " error)
|
||||
(let [setup-step (get-in db [:keycard :setup-step])
|
||||
tag-was-lost? (common/tag-lost? error)
|
||||
flow (get-in db [:keycard :flow])]
|
||||
(log/debug "[keycard] on-pair-error" setup-step "flow:" flow)
|
||||
(when-not tag-was-lost?
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :setup-error] (i18n/label :t/invalid-pairing-password))}
|
||||
(common/set-on-card-connected (if (= setup-step :pairing)
|
||||
:keycard/load-pairing-screen
|
||||
:keycard/pair))
|
||||
(common/hide-connection-sheet)
|
||||
(when (= flow :import)
|
||||
(navigation/navigate-to :keycard-recovery-pair nil))
|
||||
(when (not= setup-step :enter-pair-code)
|
||||
(common/process-error code error))))))
|
||||
|
||||
(rf/defn set-setup-step
|
||||
[{:keys [db]} card-state]
|
||||
{:db (assoc-in db
|
||||
[:keycard :setup-step]
|
||||
(case card-state
|
||||
:not-paired :pair
|
||||
:no-pairing-slots :no-slots
|
||||
:init :card-ready
|
||||
:profile/profile :import-multiaccount
|
||||
:begin))})
|
||||
|
||||
(rf/defn show-no-keycard-applet-alert
|
||||
[_]
|
||||
{:effects.utils/show-confirmation {:title (i18n/label :t/no-keycard-applet-on-card)
|
||||
:content (i18n/label
|
||||
:t/keycard-applet-install-instructions)
|
||||
:cancel-button-text ""
|
||||
:confirm-button-text :t/okay}})
|
||||
|
||||
;; NOTE: Maybe replaced by multiple events based on on flow to make it easier to maintain.
|
||||
;; Because there are many execution paths it is harder to follow all possible states.
|
||||
(rf/defn check-card-state
|
||||
{:events [:keycard/check-card-state]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [app-info (get-in db [:keycard :application-info])
|
||||
flow (get-in db [:keycard :flow])
|
||||
{:keys [instance-uid key-uid paired?]} app-info
|
||||
card-state (common/get-card-state app-info)]
|
||||
(log/debug "[keycard] check-card-state"
|
||||
"card-state" card-state
|
||||
"flow" flow)
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :card-state] card-state)}
|
||||
(set-setup-step card-state)
|
||||
|
||||
(when paired?
|
||||
(load-pairing))
|
||||
|
||||
(if (and flow
|
||||
(= card-state :init))
|
||||
(proceed-setup-with-initialized-card flow instance-uid paired?)
|
||||
(common/hide-connection-sheet))
|
||||
|
||||
(when (= card-state :pre-init)
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to :keycard-recovery-no-key nil)
|
||||
(fn [cofx]
|
||||
(rf/merge
|
||||
cofx
|
||||
(common/clear-on-card-read)
|
||||
(load-pin-screen)))))
|
||||
|
||||
(when (and (= card-state :profile/profile)
|
||||
(= flow :import))
|
||||
(if (common/find-multiaccount-by-key-uid db key-uid)
|
||||
;; reimplement
|
||||
;;(multiaccounts.recover/show-existing-multiaccount-alert key-uid)
|
||||
(if paired?
|
||||
(load-recovery-pin-screen)
|
||||
(recovery/load-pair-screen))))
|
||||
|
||||
(when (= card-state :blank)
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to :keycard-recovery-no-key nil)
|
||||
(show-no-keycard-applet-alert)))
|
||||
|
||||
(when (and (= card-state :profile/profile)
|
||||
(#{:create :recovery} flow))
|
||||
(show-keycard-has-multiaccount-alert)))))
|
||||
|
||||
(rf/defn on-card-connected
|
||||
{:events [:keycard.callback/on-card-connected]}
|
||||
[{:keys [db]} _]
|
||||
(log/debug "[keycard] card globally connected")
|
||||
{:db (assoc-in db [:keycard :card-connected?] true)})
|
||||
|
||||
(rf/defn on-card-disconnected
|
||||
{:events [:keycard.callback/on-card-disconnected]}
|
||||
[{:keys [db]} _]
|
||||
(log/debug "[keycard] card disconnected")
|
||||
{:db (assoc-in db [:keycard :card-connected?] false)})
|
||||
|
||||
(rf/defn on-nfc-user-cancelled
|
||||
{:events [:keycard.callback/on-nfc-user-cancelled]}
|
||||
[{:keys [db]} _]
|
||||
(log/debug "[keycard] nfc user cancelled")
|
||||
{:dispatch [:signing.ui/cancel-is-pressed]})
|
||||
|
||||
(rf/defn on-nfc-timeout
|
||||
{:events [:keycard.callback/on-nfc-timeout]}
|
||||
[{:keys [db]} _]
|
||||
(log/debug "[keycard] nfc timeout")
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :nfc-running?] false)
|
||||
(assoc-in [:keycard :card-connected?] false))
|
||||
:dispatch-later [{:ms 500 :dispatch [:keycard.ui/start-nfc]}]})
|
||||
|
||||
(rf/defn on-register-card-events
|
||||
{:events [:keycard.callback/on-register-card-events]}
|
||||
[{:keys [db]} listeners]
|
||||
{:db (update-in db [:keycard :listeners] merge listeners)})
|
||||
|
||||
(rf/defn ui-recovery-phrase-cancel-pressed
|
||||
{:events [:keycard.ui/recovery-phrase-cancel-pressed]}
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :setup-step] :recovery-phrase)})
|
||||
|
||||
(rf/defn ui-pin-numpad-delete-button-pressed
|
||||
{:events [:keycard.ui/pin-numpad-delete-button-pressed]}
|
||||
[{:keys [db]} step]
|
||||
(when-not (empty? (get-in db [:keycard :pin step]))
|
||||
{:db (update-in db [:keycard :pin step] pop)}))
|
||||
|
||||
(rf/defn start-nfc
|
||||
{:events [:keycard.ui/start-nfc]}
|
||||
[cofx]
|
||||
{:keycard/start-nfc nil})
|
||||
|
||||
(rf/defn stop-nfc
|
||||
{:events [:keycard.ui/stop-nfc]}
|
||||
[cofx]
|
||||
{:keycard/stop-nfc nil
|
||||
:keycard.callback/on-card-disconnected nil})
|
||||
|
||||
(rf/defn start-nfc-success
|
||||
{:events [:keycard.callback/start-nfc-success]}
|
||||
[{:keys [db]} _]
|
||||
(log/debug "[keycard] nfc started success")
|
||||
{:db (assoc-in db [:keycard :nfc-running?] true)})
|
||||
|
||||
(rf/defn start-nfc-failure
|
||||
{:events [:keycard.callback/start-nfc-failure]}
|
||||
[{:keys [db]} _]
|
||||
(log/debug "[keycard] nfc failed starting")) ;; leave current value on :nfc-running
|
||||
|
||||
(rf/defn stop-nfc-success
|
||||
{:events [:keycard.callback/stop-nfc-success]}
|
||||
[{:keys [db]} _]
|
||||
(log/debug "[keycard] nfc stopped success")
|
||||
(log/debug "[keycard] setting card-connected? and nfc-running? to false")
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :nfc-running?] false)
|
||||
(assoc-in [:keycard :card-connected?] false))})
|
||||
|
||||
(rf/defn stop-nfc-failure
|
||||
{:events [:keycard.callback/stop-nfc-failure]}
|
||||
[{:keys [db]} _]
|
||||
(log/debug "[keycard] nfc failed stopping")) ;; leave current value on :nfc-running
|
||||
|
||||
(rf/defn init
|
||||
{:events [:keycard/init]}
|
||||
[_]
|
||||
{:keycard/register-card-events nil
|
||||
:keycard/check-nfc-support nil
|
||||
:keycard/check-nfc-enabled nil
|
||||
:keycard/retrieve-pairings nil})
|
|
@ -1,77 +0,0 @@
|
|||
(ns legacy.status-im.keycard.core-test)
|
||||
|
||||
;;TODO re-enable after fixing keycard flow
|
||||
#_(deftest process-pin-input
|
||||
(testing "start entering PIN"
|
||||
(is (= {:db {:keycard {:pin {:original [1]
|
||||
:confirmation []
|
||||
:status nil
|
||||
:enter-step :original}}}}
|
||||
(keycard/process-pin-input {:db {:keycard {:pin {:original [1]
|
||||
:confirmation []
|
||||
:enter-step :original}}}}))))
|
||||
(testing "first 6 numbers entered"
|
||||
(is (= {:db {:keycard {:pin {:original [1 2 3 4 5 6]
|
||||
:confirmation []
|
||||
:status nil
|
||||
:enter-step :confirmation}}}}
|
||||
(keycard/process-pin-input {:db {:keycard {:pin {:original [1 2 3 4 5 6]
|
||||
:confirmation []
|
||||
:enter-step :original}}}}))))
|
||||
(testing "confirmation entered"
|
||||
(is (= {:db {:keycard {:pin {:original [1 2 3 4 5 6]
|
||||
:confirmation [1 2 3 4 5 6]
|
||||
:current [1 1 1 1 1 1]
|
||||
:enter-step :confirmation
|
||||
:status :verifying}
|
||||
:card-connected? true}}
|
||||
:keycard/change-pin {:new-pin "123456"
|
||||
:current-pin "111111"
|
||||
:pairing nil}}
|
||||
(keycard/process-pin-input {:db {:keycard {:pin {:original [1 2 3 4 5 6]
|
||||
:confirmation [1 2 3 4 5 6]
|
||||
:current [1 1 1 1 1 1]
|
||||
:enter-step :confirmation}
|
||||
:card-connected? true}}}))))
|
||||
|
||||
(testing "confirmation doesn't match"
|
||||
(is (= {:db {:keycard {:pin {:original []
|
||||
:confirmation []
|
||||
:enter-step :original
|
||||
:error-label :t/pin-mismatch
|
||||
:status :error}}}}
|
||||
(keycard/process-pin-input {:db {:keycard {:pin {:original [1 2 3 4 5 6]
|
||||
:confirmation [1 2 3 4 5 7]
|
||||
:enter-step :confirmation}}}})))))
|
||||
|
||||
#_(deftest on-generate-and-load-key-success
|
||||
(is
|
||||
(=
|
||||
(select-keys
|
||||
(get-in
|
||||
(keycard/on-generate-and-load-key-success
|
||||
{:random-guid-generator (constantly "")
|
||||
:signing-phrase ""
|
||||
:status ""
|
||||
:db {}}
|
||||
#js
|
||||
{"whisper-private-key" "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
|
||||
"whisper-public-key"
|
||||
"04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
|
||||
"encryption-public-key"
|
||||
"04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
|
||||
"whisper-address" "87df2285f90b71221fab6267b7cb37532fedbb1f"
|
||||
"wallet-address" "7e92236392a850980d00d0cd2a4b92886bd7fe7b"})
|
||||
[:db :keycard :profile/profile])
|
||||
[:whisper-private-key
|
||||
:whisper-public-key
|
||||
:encryption-public-key
|
||||
:wallet-address
|
||||
:whisper-address]))
|
||||
{:whisper-private-key "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
|
||||
:whisper-public-key
|
||||
"0x04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
|
||||
:encryption-public-key
|
||||
"04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
|
||||
:whisper-address "87df2285f90b71221fab6267b7cb37532fedbb1f"
|
||||
:wallet-address "7e92236392a850980d00d0cd2a4b92886bd7fe7b"}))
|
|
@ -1,47 +0,0 @@
|
|||
(ns legacy.status-im.keycard.delete-key
|
||||
(:require
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn reset-card-pressed
|
||||
{:events [:keycard-settings.ui/reset-card-pressed]}
|
||||
[cofx]
|
||||
(navigation/navigate-to cofx :reset-card nil))
|
||||
|
||||
(rf/defn delete-card
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
multiaccount-key-uid (get-in db [:profile/profile :key-uid])]
|
||||
(if (and key-uid
|
||||
(= key-uid multiaccount-key-uid))
|
||||
{:keycard/delete nil}
|
||||
(common/unauthorized-operation cofx))))
|
||||
|
||||
(rf/defn navigate-to-reset-card-screen
|
||||
{:events [:keycard/navigate-to-reset-card-screen]}
|
||||
[cofx]
|
||||
(navigation/navigate-to cofx :reset-card nil))
|
||||
|
||||
(rf/defn reset-card-next-button-pressed
|
||||
{:events [:keycard-settings.ui/reset-card-next-button-pressed]}
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :reset-card :disabled?] true)
|
||||
:dispatch [:keycard/proceed-to-reset-card false]})
|
||||
|
||||
(rf/defn proceed-to-reset-card
|
||||
{:events [:keycard/proceed-to-reset-card]}
|
||||
[{:keys [db] :as cofx} keep-keys-on-keycard?]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:enter-step :current
|
||||
:current []
|
||||
:puk []
|
||||
:status nil
|
||||
:error-label nil
|
||||
:on-verified (if keep-keys-on-keycard?
|
||||
:keycard/unpair-and-delete
|
||||
:keycard/remove-key-with-unpair)})}
|
||||
(common/set-on-card-connected :keycard/navigate-to-enter-pin-screen)
|
||||
(common/navigate-to-enter-pin-screen)))
|
|
@ -1,13 +0,0 @@
|
|||
(ns legacy.status-im.keycard.export-key
|
||||
(:require
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn on-export-key-success
|
||||
{:events [:keycard.callback/on-export-key-success]}
|
||||
[{:keys [db] :as cofx} pubkey]
|
||||
(let [callback-fn (get-in db [:keycard :on-export-success])]
|
||||
(rf/merge cofx
|
||||
{:dispatch (callback-fn pubkey)}
|
||||
(common/clear-pin)
|
||||
(common/hide-connection-sheet))))
|
|
@ -1,208 +0,0 @@
|
|||
(ns legacy.status-im.keycard.fx
|
||||
(:require
|
||||
["@react-native-async-storage/async-storage" :default AsyncStorage]
|
||||
["react-native" :refer (BackHandler)]
|
||||
[legacy.status-im.keycard.card :as card]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/start-nfc
|
||||
(fn []
|
||||
(log/debug "fx start-nfc")
|
||||
(card/start-nfc
|
||||
{:on-success #(re-frame/dispatch [:keycard.callback/start-nfc-success])
|
||||
:on-failure #(re-frame/dispatch [:keycard.callback/start-nfc-failure])})))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/stop-nfc
|
||||
(fn []
|
||||
(log/debug "fx stop-nfc")
|
||||
(card/stop-nfc
|
||||
{:on-success #(re-frame/dispatch [:keycard.callback/stop-nfc-success])
|
||||
:on-failure #(re-frame/dispatch [:keycard.callback/stop-nfc-failure])})))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/set-nfc-message
|
||||
card/set-nfc-message)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/start-nfc-and-show-connection-sheet
|
||||
(fn [args]
|
||||
(log/debug "fx start-nfc-and-show-connection-sheet")
|
||||
(card/start-nfc
|
||||
{:on-success
|
||||
(fn []
|
||||
(log/debug "nfc started successfully. next: show-connection-sheet")
|
||||
(re-frame/dispatch [:keycard.callback/start-nfc-success])
|
||||
(re-frame/dispatch [:keycard.callback/show-connection-sheet args]))
|
||||
:on-failure
|
||||
(fn []
|
||||
(log/debug "nfc failed star starting. not calling show-connection-sheet")
|
||||
(re-frame/dispatch [:keycard.callback/start-nfc-failure]))})))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/stop-nfc-and-hide-connection-sheet
|
||||
(fn []
|
||||
(log/debug "fx stop-nfc-and-hide-connection-sheet")
|
||||
(card/stop-nfc
|
||||
{:on-success
|
||||
(fn []
|
||||
(re-frame/dispatch [:keycard.callback/stop-nfc-success])
|
||||
(re-frame/dispatch [:keycard.callback/hide-connection-sheet]))
|
||||
:on-failure
|
||||
(fn []
|
||||
(re-frame/dispatch [:keycard.callback/stop-nfc-failure]))})))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/get-application-info
|
||||
card/get-application-info)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/factory-reset
|
||||
card/factory-reset)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/check-nfc-support
|
||||
card/check-nfc-support)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/check-nfc-enabled
|
||||
card/check-nfc-enabled)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/open-nfc-settings
|
||||
card/open-nfc-settings)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/install-applet-and-init-card
|
||||
card/install-applet-and-init-card)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/init-card
|
||||
card/init-card)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/register-card-events
|
||||
card/register-card-events)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/remove-event-listeners
|
||||
card/remove-event-listeners)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/pair
|
||||
card/pair)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/generate-and-load-key
|
||||
card/generate-and-load-key)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/unblock-pin
|
||||
card/unblock-pin)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/verify-pin
|
||||
card/verify-pin)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/change-pin
|
||||
card/change-pin)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/change-puk
|
||||
card/change-puk)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/change-pairing
|
||||
card/change-pairing)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/unpair
|
||||
card/unpair)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/delete
|
||||
card/delete)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/remove-key
|
||||
card/remove-key)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/remove-key-with-unpair
|
||||
card/remove-key-with-unpair)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/export-key
|
||||
card/export-key)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/unpair-and-delete
|
||||
card/unpair-and-delete)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/import-keys
|
||||
card/import-keys)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/get-keys
|
||||
card/get-keys)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/sign
|
||||
card/sign)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/sign-typed-data
|
||||
card/sign-typed-data)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/login-with-keycard
|
||||
card/login)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:send-transaction-with-signature
|
||||
card/send-transaction-with-signature)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/persist-pairings
|
||||
(fn [pairings]
|
||||
(.. AsyncStorage
|
||||
(setItem "status-keycard-pairings" (types/serialize pairings)))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/retrieve-pairings
|
||||
(fn []
|
||||
(.. AsyncStorage
|
||||
(getItem "status-keycard-pairings")
|
||||
(then #(re-frame/dispatch [:keycard.callback/on-retrieve-pairings-success
|
||||
(types/deserialize %)])))))
|
||||
|
||||
;; TODO: Should act differently on different views
|
||||
(re-frame/reg-fx
|
||||
:keycard/listen-to-hardware-back-button
|
||||
;;NOTE: not done in view because effect should happen under different conditions and is not
|
||||
;;dependent on particular screen to be loaded. An fx is easier to re-use and test.
|
||||
(fn []
|
||||
(re-frame/dispatch [:keycard/add-listener-to-hardware-back-button
|
||||
(.addEventListener BackHandler
|
||||
"hardwareBackPress"
|
||||
(fn []
|
||||
(re-frame/dispatch [:keycard/back-button-pressed])
|
||||
true))])))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/remove-listener-to-hardware-back-button
|
||||
(fn [^js listener]
|
||||
(.remove listener)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/save-multiaccount-and-login
|
||||
card/save-multiaccount-and-login)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/delete-multiaccount-before-migration
|
||||
card/delete-multiaccount-before-migration)
|
|
@ -1,182 +0,0 @@
|
|||
(ns legacy.status-im.keycard.login
|
||||
(:require
|
||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
legacy.status-im.keycard.fx
|
||||
[legacy.status-im.keycard.onboarding :as onboarding]
|
||||
[legacy.status-im.keycard.recovery :as recovery]
|
||||
[legacy.status-im.signing.core :as signing.core]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn login-got-it-pressed
|
||||
{:events [:keycard.login.pin.ui/got-it-pressed
|
||||
:keycard.login.pin.ui/cancel-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db db}
|
||||
(navigation/pop-to-root :screen/profile.profiles)))
|
||||
|
||||
(rf/defn login-pin-more-icon-pressed
|
||||
{:events [:keycard.login.pin.ui/more-icon-pressed]}
|
||||
[cofx]
|
||||
(bottom-sheet/hide-bottom-sheet-old cofx))
|
||||
|
||||
(rf/defn login-create-key-pressed
|
||||
{:events [:keycard.login.ui/create-new-key-pressed]}
|
||||
[cofx]
|
||||
(rf/merge cofx
|
||||
(bottom-sheet/hide-bottom-sheet-old)
|
||||
(onboarding/start-onboarding-flow)))
|
||||
|
||||
(rf/defn login-add-key-pressed
|
||||
{:events [:keycard.login.ui/add-key-pressed]}
|
||||
[cofx]
|
||||
(recovery/start-import-flow cofx))
|
||||
|
||||
(rf/defn login-remember-me-changed
|
||||
{:events [:keycard.login.ui/remember-me-changed]}
|
||||
[{:keys [db] :as cofx} value]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :remember-me?] value)}))
|
||||
|
||||
(rf/defn login-pair-card-pressed
|
||||
{:events [:keycard.login.ui/pair-card-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(log/debug "[keycard] load-pair-card-pressed")
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :flow] :login)}
|
||||
(navigation/navigate-to :keycard-recovery-pair nil)))
|
||||
|
||||
(rf/defn reset-pin
|
||||
{:events [::reset-pin]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge
|
||||
cofx
|
||||
(signing.core/discard)
|
||||
(fn [{:keys [db]}]
|
||||
{:db (-> db
|
||||
(dissoc :popover/popover)
|
||||
(update-in [:keycard :pin]
|
||||
dissoc
|
||||
:reset
|
||||
:puk)
|
||||
(update-in [:keycard :pin]
|
||||
assoc
|
||||
:enter-step :reset
|
||||
:error nil
|
||||
:status nil))
|
||||
:hide-popover nil})
|
||||
(when (:profile/profile db)
|
||||
(navigation/navigate-to :my-profile nil))
|
||||
(when-not (:profile/login db)
|
||||
(if (:popover/popover db)
|
||||
(navigation/navigate-replace :keycard-pin nil)
|
||||
(navigation/navigate-to :keycard-pin nil)))))
|
||||
|
||||
(rf/defn dismiss-frozen-keycard-popover
|
||||
{:events [::frozen-keycard-popover-dismissed]}
|
||||
[{:keys [db]}]
|
||||
{:db (-> db
|
||||
(dissoc :popover/popover)
|
||||
(update :keycard dissoc :setup-step))
|
||||
:hide-popover nil})
|
||||
|
||||
(rf/defn login-with-keycard
|
||||
{:events [:keycard/login-with-keycard]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [:pin-retry-counter :puk-retry-counter]
|
||||
:as application-info}
|
||||
(get-in db [:keycard :application-info])
|
||||
|
||||
key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
paired? (get-in db [:keycard :application-info :paired?])
|
||||
multiaccount (get-in db
|
||||
[:profile/profiles-overview (get-in db [:profile/login :key-uid])])
|
||||
multiaccount-key-uid (get multiaccount :key-uid)
|
||||
multiaccount-mismatch? (or (nil? multiaccount)
|
||||
(not= multiaccount-key-uid key-uid))]
|
||||
(log/debug "[keycard] login-with-keycard"
|
||||
"empty application info" (empty? application-info)
|
||||
"no key-uid" (empty? key-uid)
|
||||
"multiaccount-mismatch?" multiaccount-mismatch?
|
||||
"no pairing" paired?)
|
||||
(cond
|
||||
(empty? application-info)
|
||||
(rf/merge cofx
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/navigate-to :not-keycard nil))
|
||||
|
||||
(empty? key-uid)
|
||||
(rf/merge cofx
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/navigate-to :keycard-blank nil))
|
||||
|
||||
multiaccount-mismatch?
|
||||
(rf/merge cofx
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/navigate-to :keycard-wrong nil))
|
||||
|
||||
(not paired?)
|
||||
(rf/merge cofx
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/navigate-to :keycard-unpaired nil))
|
||||
|
||||
(and (zero? pin-retry-counter)
|
||||
(or (nil? puk-retry-counter)
|
||||
(pos? puk-retry-counter)))
|
||||
nil
|
||||
|
||||
:else
|
||||
(common/get-keys-from-keycard cofx))))
|
||||
|
||||
(rf/defn proceed-to-login
|
||||
{:events [::login-after-reset]}
|
||||
[cofx]
|
||||
(log/debug "[keycard] proceed-to-login")
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:sheet-options {:on-cancel [::common/cancel-sheet-confirm]}
|
||||
:on-card-connected :keycard/get-application-info
|
||||
:on-card-read :keycard/login-with-keycard
|
||||
:handler (common/get-application-info :keycard/login-with-keycard)}))
|
||||
|
||||
(rf/defn on-keycard-keychain-keys
|
||||
{:events [:multiaccounts.login.callback/get-keycard-keys-success]}
|
||||
[{:keys [db] :as cofx} key-uid [encryption-public-key whisper-private-key :as creds]]
|
||||
(if (nil? creds)
|
||||
(navigation/set-stack-root cofx
|
||||
:multiaccounts-stack
|
||||
[:multiaccounts
|
||||
:keycard-login-pin])
|
||||
(let [{:keys [name]} (get-in db [:profile/profiles-overview key-uid])
|
||||
multiaccount-data (types/clj->json {:name name
|
||||
:key-uid key-uid})
|
||||
account-data {:key-uid key-uid
|
||||
:encryption-public-key encryption-public-key
|
||||
:whisper-private-key whisper-private-key}]
|
||||
{:db
|
||||
(-> db
|
||||
(assoc-in [:keycard :pin :status] nil)
|
||||
(assoc-in [:keycard :pin :login] [])
|
||||
(assoc-in [:keycard :profile/profile]
|
||||
(update account-data :whisper-public-key address/normalized-hex))
|
||||
(assoc-in [:keycard :flow] nil)
|
||||
(update :profile/login assoc
|
||||
:password encryption-public-key
|
||||
:key-uid key-uid
|
||||
:name name
|
||||
:save-password? true))
|
||||
:keycard/login-with-keycard
|
||||
{:multiaccount-data multiaccount-data
|
||||
:key-uid key-uid
|
||||
:password encryption-public-key
|
||||
:chat-key whisper-private-key}})))
|
||||
|
||||
(rf/defn on-login-success
|
||||
{:events [:keycard.login.callback/login-success]}
|
||||
[_ result]
|
||||
(log/debug "loginWithKeycard success: " result))
|
|
@ -1,37 +0,0 @@
|
|||
(ns legacy.status-im.keycard.mnemonic
|
||||
(:require
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
legacy.status-im.keycard.fx
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn set-mnemonic
|
||||
[{:keys [db] :as cofx}]
|
||||
(log/debug "[keycard] set-mnemonic")
|
||||
(let [selected-id (get-in db [:intro-wizard :selected-id])
|
||||
mnemonic (reduce
|
||||
(fn [_ {:keys [id mnemonic]}]
|
||||
(when (= selected-id id)
|
||||
(reduced mnemonic)))
|
||||
nil
|
||||
(get-in db [:intro-wizard :multiaccounts]))]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] :recovery-phrase)
|
||||
(assoc-in [:keycard :secrets :mnemonic] mnemonic))}
|
||||
(common/clear-on-card-connected)
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/navigate-replace :keycard-onboarding-recovery-phrase nil))))
|
||||
|
||||
(rf/defn load-loading-keys-screen
|
||||
{:events [:keycard.ui/recovery-phrase-confirm-pressed
|
||||
:keycard/load-loading-keys-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :setup-step] :loading-keys)}
|
||||
(common/show-connection-sheet
|
||||
{:on-card-connected :keycard/load-loading-keys-screen
|
||||
:handler (common/dispatch-event :keycard/generate-and-load-key)})))
|
|
@ -1,11 +0,0 @@
|
|||
(ns legacy.status-im.keycard.nfc)
|
||||
|
||||
(def is-nfc-supported? (atom nil))
|
||||
|
||||
(defn set-nfc-supported?
|
||||
[supported?]
|
||||
(reset! is-nfc-supported? supported?))
|
||||
|
||||
(defn nfc-supported?
|
||||
[]
|
||||
@is-nfc-supported?)
|
|
@ -1,335 +0,0 @@
|
|||
(ns legacy.status-im.keycard.onboarding
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
legacy.status-im.keycard.fx
|
||||
[legacy.status-im.keycard.mnemonic :as mnemonic]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.utils.utils :as utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn begin-setup-button-pressed
|
||||
{:keys [:keycard.ui/begin-setup-button-pressed]}
|
||||
[{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] :pin)
|
||||
(assoc-in [:keycard :pin :enter-step] :original)
|
||||
(assoc-in [:keycard :pin :original] [])
|
||||
(assoc-in [:keycard :pin :confirmation] []))})
|
||||
|
||||
(rf/defn start-installation
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-state (get-in db [:keycard :card-state])
|
||||
pin (common/vector->string (get-in db [:keycard :pin :original]))]
|
||||
(log/debug "start-installation: card-state" card-state)
|
||||
(case card-state
|
||||
|
||||
:pre-init
|
||||
{:keycard/init-card pin}
|
||||
|
||||
(do
|
||||
(log/debug (str "Cannot start keycard installation from state: " card-state))
|
||||
(rf/merge cofx
|
||||
{:effects.utils/show-popup {:title (i18n/label :t/error)
|
||||
:content (i18n/label :t/something-went-wrong)}}
|
||||
(navigation/navigate-to :keycard-authentication-method nil))))))
|
||||
|
||||
(rf/defn load-preparing-screen
|
||||
{:events [:keycard/load-preparing-screen]}
|
||||
[cofx]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:sheet-options {:on-cancel [::cancel-pressed]}
|
||||
:on-card-connected :keycard/load-preparing-screen
|
||||
:handler start-installation}))
|
||||
|
||||
(rf/defn load-pairing-screen
|
||||
{:events [:keycard/load-pairing-screen
|
||||
:keycard.onboarding.puk-code.ui/confirm-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :setup-step] :pairing)}
|
||||
(common/show-connection-sheet
|
||||
{:sheet-options {:on-cancel [::cancel-pressed]}
|
||||
:on-card-connected :keycard/load-pairing-screen
|
||||
:handler (common/dispatch-event :keycard/pair)})))
|
||||
|
||||
(rf/defn puk-code-next-pressed
|
||||
{:events [:keycard.onboarding.puk-code.ui/next-pressed]}
|
||||
[_]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/secret-keys-confirmation-title)
|
||||
:content (i18n/label :t/secret-keys-confirmation-text)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/cancel)
|
||||
:on-accept #(re-frame/dispatch
|
||||
[:keycard.onboarding.puk-code.ui/confirm-pressed])
|
||||
:on-cancel #()}})
|
||||
|
||||
(rf/defn load-finishing-screen
|
||||
{:events [:keycard.onboarding.recovery-phrase-confirm-word2.ui/next-pressed
|
||||
:keycard/load-finishing-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:keycard :setup-step] :loading-keys)}
|
||||
(common/show-connection-sheet
|
||||
{:sheet-options {:on-cancel [::cancel-pressed]}
|
||||
:on-card-connected :keycard/load-finishing-screen
|
||||
:handler (common/dispatch-event :keycard/generate-and-load-key)})))
|
||||
|
||||
(rf/defn recovery-phrase-learn-more-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase.ui/learn-more-pressed]}
|
||||
[_]
|
||||
(.openURL ^js react/linking constants/keycard-integration-link))
|
||||
|
||||
(rf/defn recovery-phrase-next-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase.ui/next-pressed
|
||||
:keycard.ui/recovery-phrase-next-button-pressed]}
|
||||
[_]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/keycard-recovery-phrase-confirmation-title)
|
||||
:content (i18n/label :t/keycard-recovery-phrase-confirmation-text)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/cancel)
|
||||
:on-accept #(re-frame/dispatch
|
||||
[:keycard.onboarding.recovery-phrase.ui/confirm-pressed])
|
||||
:on-cancel #()}})
|
||||
|
||||
(rf/defn recovery-phrase-start-confirmation
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [mnemonic (get-in db [:keycard :secrets :mnemonic])
|
||||
[word1 word2] (shuffle (map-indexed vector (clojure.string/split mnemonic #" ")))
|
||||
word1 (zipmap [:idx :word] word1)
|
||||
word2 (zipmap [:idx :word] word2)]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] :recovery-phrase-confirm-word1)
|
||||
(assoc-in [:keycard :recovery-phrase :step] :word1)
|
||||
(assoc-in [:keycard :recovery-phrase :confirm-error] nil)
|
||||
(assoc-in [:keycard :recovery-phrase :input-word] nil)
|
||||
(assoc-in [:keycard :recovery-phrase :word1] word1)
|
||||
(assoc-in [:keycard :recovery-phrase :word2] word2))}
|
||||
(common/remove-listener-to-hardware-back-button))))
|
||||
|
||||
(rf/defn recovery-phrase-confirm-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase.ui/confirm-pressed]}
|
||||
[cofx]
|
||||
(rf/merge cofx
|
||||
(recovery-phrase-start-confirmation)
|
||||
(navigation/navigate-to :keycard-onboarding-recovery-phrase-confirm-word1 nil)))
|
||||
|
||||
(rf/defn recovery-phrase-next-word
|
||||
[{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :recovery-phrase :step] :word2)
|
||||
(assoc-in [:keycard :recovery-phrase :confirm-error] nil)
|
||||
(assoc-in [:keycard :recovery-phrase :input-word] nil)
|
||||
(assoc-in [:keycard :setup-step] :recovery-phrase-confirm-word2))})
|
||||
|
||||
(rf/defn proceed-with-generating-key
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin (get-in db
|
||||
[:keycard :secrets :pin]
|
||||
(common/vector->string (get-in db [:keycard :pin :current])))]
|
||||
(if (empty? pin)
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin]
|
||||
{:enter-step :current
|
||||
:on-verified :keycard/generate-and-load-key
|
||||
:current []})
|
||||
(assoc-in [:keycard :setup-step] :loading-keys))}
|
||||
(navigation/navigate-to :keycard-onboarding-pin nil))
|
||||
(load-finishing-screen cofx))))
|
||||
|
||||
(rf/defn recovery-phrase-confirm-word-next-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase-confirm-word.ui/next-pressed
|
||||
:keycard.onboarding.recovery-phrase-confirm-word.ui/input-submitted]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [step (get-in db [:keycard :recovery-phrase :step])
|
||||
input-word (get-in db [:keycard :recovery-phrase :input-word])
|
||||
{:keys [word]} (get-in db [:keycard :recovery-phrase step])]
|
||||
(if (= word input-word)
|
||||
(if (= (:view-id db) :keycard-onboarding-recovery-phrase-confirm-word1)
|
||||
(rf/merge cofx
|
||||
(recovery-phrase-next-word)
|
||||
(navigation/navigate-replace :keycard-onboarding-recovery-phrase-confirm-word2 nil))
|
||||
(proceed-with-generating-key cofx))
|
||||
{:db (assoc-in db [:keycard :recovery-phrase :confirm-error] (i18n/label :t/wrong-word))})))
|
||||
|
||||
(rf/defn recovery-phrase-confirm-word-input-changed
|
||||
{:events [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-changed]}
|
||||
[{:keys [db]} input]
|
||||
{:db (assoc-in db [:keycard :recovery-phrase :input-word] input)})
|
||||
|
||||
(rf/defn pair-code-input-changed
|
||||
{:events [:keycard.onboarding.pair.ui/input-changed]}
|
||||
[{:keys [db]} input]
|
||||
{:db (assoc-in db [:keycard :secrets :password] input)})
|
||||
|
||||
(rf/defn keycard-option-pressed
|
||||
{:events [:onboarding.ui/keycard-option-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [flow (get-in db [:keycard :flow])]
|
||||
(rf/merge cofx
|
||||
{:keycard/check-nfc-enabled nil}
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to :keycard-recovery-intro nil)
|
||||
(do
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to :keycard-onboarding-intro nil))))))
|
||||
|
||||
(rf/defn start-onboarding-flow
|
||||
{:events [:keycard/start-onboarding-flow]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :flow] :create)
|
||||
:keycard/check-nfc-enabled nil}
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to :keycard-onboarding-intro nil)))
|
||||
|
||||
(rf/defn open-nfc-settings-pressed
|
||||
{:events [:keycard.onboarding.nfc-on/open-nfc-settings-pressed]}
|
||||
[_]
|
||||
{:keycard/open-nfc-settings nil})
|
||||
|
||||
(defn- show-recover-confirmation
|
||||
[]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/are-you-sure?)
|
||||
:content (i18n/label :t/are-you-sure-description)
|
||||
:confirm-button-text (clojure.string/upper-case (i18n/label :t/yes))
|
||||
:cancel-button-text (i18n/label :t/see-it-again)
|
||||
:on-accept #(re-frame/dispatch
|
||||
[:keycard.ui/recovery-phrase-confirm-pressed])
|
||||
:on-cancel #(re-frame/dispatch
|
||||
[:keycard.ui/recovery-phrase-cancel-pressed])}})
|
||||
|
||||
(rf/defn recovery-phrase-confirm-word
|
||||
{:events [:keycard.ui/recovery-phrase-confirm-word-next-button-pressed]}
|
||||
[{:keys [db]}]
|
||||
(let [step (get-in db [:keycard :recovery-phrase :step])
|
||||
input-word (get-in db [:keycard :recovery-phrase :input-word])
|
||||
{:keys [word]} (get-in db [:keycard :recovery-phrase step])]
|
||||
(if (= word input-word)
|
||||
(if (= step :word1)
|
||||
(recovery-phrase-next-word db)
|
||||
(show-recover-confirmation))
|
||||
{:db (assoc-in db [:keycard :recovery-phrase :confirm-error] (i18n/label :t/wrong-word))})))
|
||||
|
||||
(rf/defn recovery-phrase-next-button-pressed
|
||||
[{:keys [db] :as cofx}]
|
||||
(if (= (get-in db [:keycard :flow]) :create)
|
||||
(recovery-phrase-start-confirmation cofx)
|
||||
(let [mnemonic (get-in db [:multiaccounts/recover :passphrase])]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :secrets :mnemonic] mnemonic)}
|
||||
(mnemonic/load-loading-keys-screen)))))
|
||||
|
||||
(rf/defn on-install-applet-and-init-card-success
|
||||
{:events [:keycard.callback/on-install-applet-and-init-card-success
|
||||
:keycard.callback/on-init-card-success]}
|
||||
[{:keys [db] :as cofx} secrets]
|
||||
(let [secrets' (js->clj secrets :keywordize-keys true)]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :card-state] :init)
|
||||
(assoc-in [:keycard :setup-step] :secret-keys)
|
||||
(update-in [:keycard :secrets] merge secrets'))}
|
||||
(common/show-connection-sheet
|
||||
{:on-card-connected :keycard/get-application-info
|
||||
:on-card-read :keycard/check-card-state
|
||||
:handler (common/get-application-info :keycard/check-card-state)}))))
|
||||
|
||||
(rf/defn on-install-applet-and-init-card-error
|
||||
{:events [:keycard.callback/on-install-applet-and-init-card-error
|
||||
:keycard.callback/on-init-card-error]}
|
||||
[{:keys [db] :as cofx} {:keys [code error]}]
|
||||
(log/debug "[keycard] install applet and init card error: " error)
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :setup-error] error)}
|
||||
(common/set-on-card-connected :keycard/load-preparing-screen)
|
||||
(common/process-error code error)))
|
||||
|
||||
(rf/defn generate-and-load-key
|
||||
{:events [:keycard/generate-and-load-key]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [pin]}
|
||||
(get-in db [:keycard :secrets])
|
||||
|
||||
{:keys [selected-id multiaccounts]}
|
||||
(:intro-wizard db)
|
||||
|
||||
multiaccount (or (->> multiaccounts
|
||||
(filter #(= (:id %) selected-id))
|
||||
first)
|
||||
(assoc (get-in db [:intro-wizard :root-key])
|
||||
:derived
|
||||
(get-in db [:intro-wizard :derived])))
|
||||
recovery-mnemonic (get-in db [:intro-wizard :passphrase])
|
||||
mnemonic (or (:mnemonic multiaccount)
|
||||
recovery-mnemonic)
|
||||
pin' (or pin
|
||||
(common/vector->string (get-in db
|
||||
[:keycard :pin
|
||||
:current])))]
|
||||
{:keycard/generate-and-load-key
|
||||
{:mnemonic mnemonic
|
||||
:pin pin'
|
||||
:key-uid (:key-uid multiaccount)
|
||||
:delete-multiaccount? (get-in db [:keycard :delete-account?])}}))
|
||||
|
||||
(rf/defn factory-reset-card-toggle
|
||||
{:events [:keycard.onboarding.intro.ui/factory-reset-card-toggle]}
|
||||
[{:keys [db] :as cofx} checked?]
|
||||
{:db (assoc-in db [:keycard :factory-reset-card?] checked?)})
|
||||
|
||||
(rf/defn begin-setup-pressed
|
||||
{:events [:keycard.onboarding.intro.ui/begin-setup-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(update :keycard
|
||||
dissoc
|
||||
:secrets
|
||||
:card-state :multiaccount-wallet-address
|
||||
:multiaccount-whisper-public-key :application-info)
|
||||
(assoc-in [:keycard :setup-step] :begin)
|
||||
(assoc-in [:keycard :pin :on-verified] nil))}
|
||||
(if (get-in db [:keycard :factory-reset-card?])
|
||||
(utils/show-confirmation {:title (i18n/label :t/keycard-factory-reset-title)
|
||||
:content (i18n/label :t/keycard-factory-reset-text)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/no)
|
||||
:on-accept #(re-frame/dispatch [::factory-reset])
|
||||
:on-cancel #(re-frame/dispatch [::factory-reset-cancel])})
|
||||
(common/show-connection-sheet
|
||||
{:on-card-connected :keycard/get-application-info
|
||||
:on-card-read :keycard/check-card-state
|
||||
:handler (common/get-application-info :keycard/check-card-state)}))))
|
||||
|
||||
(rf/defn factory-reset
|
||||
{:events [::factory-reset]}
|
||||
[cofx]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:on-card-connected :keycard/factory-reset
|
||||
:on-card-read :keycard/check-card-state
|
||||
:handler (common/factory-reset :keycard/check-card-state)}))
|
||||
|
||||
(rf/defn factory-reset-cancel
|
||||
{:events [::factory-reset-cancel]}
|
||||
[{:keys [db] :as cofx}]
|
||||
{:db (update db :keycard dissoc :factory-reset-card?)})
|
||||
|
||||
(rf/defn cancel-pressed
|
||||
{:events [::cancel-pressed]}
|
||||
[cofx]
|
||||
(rf/merge cofx
|
||||
(navigation/navigate-back)
|
||||
(common/cancel-sheet-confirm)))
|
|
@ -1,355 +0,0 @@
|
|||
(ns legacy.status-im.keycard.recovery
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
legacy.status-im.keycard.fx
|
||||
[legacy.status-im.multiaccounts.create.core :as multiaccounts.create]
|
||||
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
|
||||
[legacy.status-im.popover.core :as popover]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/defn pair*
|
||||
[_ password]
|
||||
{:keycard/pair {:password password}})
|
||||
|
||||
(rf/defn pair
|
||||
{:events [:keycard/pair]}
|
||||
[cofx]
|
||||
(let [{:keys [password]} (get-in cofx [:db :keycard :secrets])]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:on-card-connected :keycard/pair
|
||||
:handler (pair* password)})))
|
||||
|
||||
(rf/defn pair-code-next-button-pressed
|
||||
{:events [:keycard.onboarding.pair.ui/input-submitted
|
||||
:keycard.ui/pair-code-next-button-pressed
|
||||
:keycard.onboarding.pair.ui/next-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pairing (get-in db [:keycard :secrets :pairing])
|
||||
paired-on (get-in db [:keycard :secrets :paired-on] (datetime/timestamp))]
|
||||
(rf/merge cofx
|
||||
(if pairing
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] :import-multiaccount)
|
||||
(assoc-in [:keycard :secrets :paired-on] paired-on))}
|
||||
(pair)))))
|
||||
|
||||
(rf/defn load-pair-screen
|
||||
[{:keys [db] :as cofx}]
|
||||
(log/debug "[keycard] load-pair-screen")
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] :pair))
|
||||
:dispatch [:bottom-sheet/hide-old]}
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to :keycard-recovery-pair nil)))
|
||||
|
||||
(rf/defn keycard-storage-selected-for-recovery
|
||||
{:events [:recovery.ui/keycard-storage-selected]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :flow] :recovery)}
|
||||
(navigation/navigate-to :keycard-recovery-enter-mnemonic nil)))
|
||||
|
||||
(rf/defn start-import-flow
|
||||
{:events [::recover-with-keycard-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db
|
||||
(-> db
|
||||
(assoc-in [:keycard :flow] :import)
|
||||
(assoc :recovered-account? true))
|
||||
:keycard/check-nfc-enabled nil}
|
||||
(bottom-sheet/hide-bottom-sheet-old)
|
||||
(navigation/navigate-to-within-stack [:keycard-recovery-intro
|
||||
:screen/onboarding.new-to-status])))
|
||||
|
||||
(rf/defn access-key-pressed
|
||||
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
|
||||
[_]
|
||||
{:dispatch [:bottom-sheet/show-sheet-old :recover-sheet]})
|
||||
|
||||
(rf/defn recovery-keycard-selected
|
||||
{:events [:recovery.ui/keycard-option-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :flow] :recovery)
|
||||
:keycard/check-nfc-enabled nil}
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to :keycard-onboarding-intro nil)))
|
||||
|
||||
(rf/defn cancel-pressed
|
||||
{:events [::cancel-pressed]}
|
||||
[cofx]
|
||||
(rf/merge cofx
|
||||
(common/cancel-sheet-confirm)
|
||||
(navigation/navigate-back)))
|
||||
|
||||
(rf/defn begin-setup-pressed
|
||||
{:events [:keycard.recovery.intro.ui/begin-recovery-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(update :keycard
|
||||
dissoc
|
||||
:secrets
|
||||
:card-state :multiaccount-wallet-address
|
||||
:multiaccount-whisper-public-key
|
||||
:application-info)
|
||||
(assoc-in [:keycard :setup-step] :begin)
|
||||
(assoc-in [:keycard :pin :on-verified] nil))}
|
||||
(common/show-connection-sheet
|
||||
{:on-card-connected :keycard/get-application-info
|
||||
:on-card-read :keycard/check-card-state
|
||||
:sheet-options {:on-cancel [::cancel-pressed]}
|
||||
:handler (common/get-application-info :keycard/check-card-state)})))
|
||||
|
||||
(rf/defn recovery-success-finish-pressed
|
||||
{:events [:keycard.recovery.success/finish-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (update db
|
||||
:keycard dissoc
|
||||
:multiaccount-wallet-address
|
||||
:multiaccount-whisper-public-key)}
|
||||
(navigation/navigate-to (if platform/android?
|
||||
:notifications-settings
|
||||
:screen/onboarding.welcome)
|
||||
nil)))
|
||||
|
||||
(rf/defn intro-wizard
|
||||
{:events [:multiaccounts.create.ui/intro-wizard]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [accs (get db :profile/profiles-overview)]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(update :keycard dissoc :flow)
|
||||
(dissoc :restored-account?))}
|
||||
(if (pos? (count accs))
|
||||
(navigation/navigate-to :get-your-keys nil)
|
||||
(navigation/set-stack-root :onboarding [:get-your-keys])))))
|
||||
|
||||
(rf/defn recovery-no-key
|
||||
{:events [:keycard.recovery.no-key.ui/generate-key-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :flow] :create)
|
||||
:keycard/check-nfc-enabled nil}
|
||||
(intro-wizard)))
|
||||
|
||||
;; NOTE: currently non functional, keycard needs to be reimplemented
|
||||
(rf/defn create-keycard-multiaccount
|
||||
{:events [::create-keycard-multiaccount]
|
||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
||||
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{{:keys [secrets flow] :profile/keys [profile]} :keycard} db
|
||||
{:keys [address
|
||||
name
|
||||
public-key
|
||||
whisper-public-key
|
||||
wallet-public-key
|
||||
wallet-root-public-key
|
||||
whisper-address
|
||||
wallet-address
|
||||
wallet-root-address
|
||||
whisper-private-key
|
||||
encryption-public-key
|
||||
instance-uid
|
||||
key-uid
|
||||
recovered]}
|
||||
profile
|
||||
{:keys [pairing paired-on]} secrets
|
||||
{:keys [name]}
|
||||
(if (nil? name)
|
||||
;; name might have been generated during recovery via passphrase
|
||||
(get-in db [:intro-wizard :derived constants/path-whisper-keyword])
|
||||
{:name name})]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] nil)
|
||||
(dissoc :intro-wizard))})))
|
||||
|
||||
(rf/defn return-to-keycard-login
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(update-in [:keycard :pin]
|
||||
assoc
|
||||
:enter-step :login
|
||||
:status nil
|
||||
:login [])
|
||||
(update :keycard dissoc :application-info))}
|
||||
(navigation/set-stack-root :multiaccounts-stack
|
||||
[:multiaccounts
|
||||
:keycard-login-pin])))
|
||||
|
||||
(rf/defn on-backup-success
|
||||
[{:keys [db] :as cofx} backup-type]
|
||||
(rf/merge cofx
|
||||
{:effects.utils/show-popup {:title (i18n/label (if (= backup-type :recovery-card)
|
||||
:t/keycard-access-reset
|
||||
:t/keycard-backup-success-title))
|
||||
:content (i18n/label (if (= backup-type :recovery-card)
|
||||
:t/keycard-can-use-with-new-passcode
|
||||
:t/keycard-backup-success-body))}}
|
||||
(cond
|
||||
(multiaccounts.model/logged-in? db)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])
|
||||
|
||||
(:profile/login db)
|
||||
(return-to-keycard-login)
|
||||
|
||||
:else
|
||||
(navigation/set-stack-root :onboarding [:get-your-keys]))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::finish-migration
|
||||
(fn [[account settings password encryption-pass login-params]]
|
||||
(native-module/convert-to-keycard-account
|
||||
account
|
||||
settings
|
||||
password
|
||||
encryption-pass
|
||||
#(let [{:keys [error]} (types/json->clj %)]
|
||||
(if (string/blank? error)
|
||||
(native-module/login-with-keycard
|
||||
(assoc login-params :node-config {:ProcessBackedupMessages true}))
|
||||
(throw
|
||||
(js/Error.
|
||||
"Please shake the phone to report this error and restart the app. Migration failed unexpectedly.")))))))
|
||||
|
||||
(rf/defn migrate-account
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pairing (get-in db [:keycard :secrets :pairing])
|
||||
paired-on (get-in db [:keycard :secrets :paired-on])
|
||||
instance-uid (get-in db [:keycard :profile/profile :instance-uid])
|
||||
account (-> db
|
||||
:profile/login
|
||||
(assoc :keycard-pairing pairing)
|
||||
(assoc :save-password? false))
|
||||
key-uid (-> account :key-uid)
|
||||
settings {:keycard-instance-uid instance-uid
|
||||
:keycard-paired-on paired-on
|
||||
:keycard-pairing pairing}
|
||||
password (native-module/sha3 (security/safe-unmask-data (get-in db
|
||||
[:keycard
|
||||
:migration-password])))
|
||||
encryption-pass (get-in db [:keycard :profile/profile :encryption-public-key])
|
||||
login-params {:key-uid key-uid
|
||||
:multiaccount-data (types/clj->json account)
|
||||
:password encryption-pass
|
||||
:chat-key (get-in db
|
||||
[:keycard :profile/profile :whisper-private-key])}]
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/profiles-overview key-uid :keycard-pairing] pairing)
|
||||
(assoc :profile/login account)
|
||||
(assoc :auth-method "none")
|
||||
(update :keycard dissoc :flow :migration-password)
|
||||
(dissoc :recovered-account?))
|
||||
::finish-migration [account settings password encryption-pass login-params]}))
|
||||
|
||||
(rf/defn delete-multiaccount
|
||||
[{:keys [db]}]
|
||||
(let [key-uid (get-in db [:profile/login :key-uid])]
|
||||
{:keycard/delete-multiaccount-before-migration
|
||||
{:key-uid key-uid
|
||||
:on-error #(re-frame/dispatch [::delete-multiaccount-error %])
|
||||
:on-success #(re-frame/dispatch [::create-keycard-multiaccount])}}))
|
||||
|
||||
(rf/defn handle-delete-multiaccount-error
|
||||
{:events [::delete-multiaccount-error]}
|
||||
[cofx _]
|
||||
(popover/show-popover cofx {:view :transfer-multiaccount-unknown-error}))
|
||||
|
||||
(rf/defn on-generate-and-load-key-success
|
||||
{:events [:keycard.callback/on-generate-and-load-key-success]
|
||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
||||
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
|
||||
[{:keys [db random-guid-generator] :as cofx} data]
|
||||
(let [account-data (js->clj data :keywordize-keys true)
|
||||
backup? (get-in db [:keycard :creating-backup?])
|
||||
migration? (get-in db [:keycard :converting-account?])]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(assoc-in
|
||||
[:keycard :profile/profile]
|
||||
(-> account-data
|
||||
(update :address address/normalized-hex)
|
||||
(update :whisper-address address/normalized-hex)
|
||||
(update :wallet-address address/normalized-hex)
|
||||
(update :wallet-root-address address/normalized-hex)
|
||||
(update :public-key address/normalized-hex)
|
||||
(update :whisper-public-key address/normalized-hex)
|
||||
(update :wallet-public-key address/normalized-hex)
|
||||
(update :wallet-root-public-key address/normalized-hex)
|
||||
(update :instance-uid #(get-in db [:keycard :profile/profile :instance-uid] %))))
|
||||
(assoc-in [:keycard :multiaccount-wallet-address] (:wallet-address account-data))
|
||||
(assoc-in [:keycard :multiaccount-whisper-public-key] (:whisper-public-key account-data))
|
||||
(assoc-in [:keycard :pin :status] nil)
|
||||
(assoc-in [:keycard :application-info :key-uid]
|
||||
(address/normalized-hex (:key-uid account-data)))
|
||||
(update :keycard dissoc :recovery-phrase :creating-backup? :converting-account?)
|
||||
(update-in [:keycard :secrets] dissoc :pin :puk :password :mnemonic)
|
||||
(assoc :multiaccounts/new-installation-id (random-guid-generator)))}
|
||||
(common/remove-listener-to-hardware-back-button)
|
||||
(common/hide-connection-sheet)
|
||||
(cond backup? (on-backup-success backup?)
|
||||
migration? (migrate-account)
|
||||
|
||||
(get-in db [:keycard :delete-account?])
|
||||
(delete-multiaccount)
|
||||
|
||||
:else (create-keycard-multiaccount)))))
|
||||
|
||||
(rf/defn on-generate-and-load-key-error
|
||||
{:events [:keycard.callback/on-generate-and-load-key-error]}
|
||||
[{:keys [db] :as cofx} {:keys [error code]}]
|
||||
(log/debug "[keycard] generate and load key error: " error)
|
||||
(when-not (common/tag-lost? error)
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :setup-error] error)}
|
||||
(common/set-on-card-connected :keycard/load-loading-keys-screen)
|
||||
(common/process-error code error))))
|
||||
|
||||
(rf/defn import-multiaccount
|
||||
{:events [:keycard/import-multiaccount]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [pairing]} (get-in db [:keycard :secrets])
|
||||
instance-uid (get-in db [:keycard :application-info :instance-uid])
|
||||
key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
pairing' (or pairing (common/get-pairing db key-uid))
|
||||
pin (common/vector->string (get-in db [:keycard :pin :import-multiaccount]))]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :profile/profile :instance-uid] instance-uid)
|
||||
(assoc-in [:keycard :pin :status] :verifying)
|
||||
(assoc-in [:keycard :secrets]
|
||||
{:pairing pairing'
|
||||
:paired-on (datetime/timestamp)}))
|
||||
:keycard/import-keys
|
||||
{:pin pin
|
||||
:on-success :keycard.callback/on-generate-and-load-key-success}})))
|
||||
|
||||
(rf/defn load-recovering-key-screen
|
||||
{:events [:keycard/load-recovering-key-screen]}
|
||||
[cofx]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:on-card-connected :keycard/load-recovering-key-screen
|
||||
:handler (common/dispatch-event :keycard/import-multiaccount)}))
|
|
@ -1,196 +0,0 @@
|
|||
(ns legacy.status-im.keycard.sign
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn sign
|
||||
{:events [:keycard/sign]}
|
||||
[{:keys [db] :as cofx} hash on-success]
|
||||
(let [card-connected? (get-in db [:keycard :card-connected?])
|
||||
key-uid (get-in db [:profile/profile :key-uid])
|
||||
keycard-key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
keycard-pin-retries (get-in db [:keycard :application-info :pin-retry-counter])
|
||||
keycard-match? (= key-uid keycard-key-uid)
|
||||
hash (or hash (get-in db [:keycard :hash]))
|
||||
data (get-in db [:keycard :data])
|
||||
typed? (get-in db [:keycard :typed?])
|
||||
pin (common/vector->string (get-in db [:keycard :pin :sign]))
|
||||
from (or (get-in db [:signing/tx :from :address])
|
||||
(get-in db [:signing/tx :message :from]))
|
||||
path (reduce
|
||||
(fn [_ {:keys [address path]}]
|
||||
(when (address/address= from address)
|
||||
(reduced path)))
|
||||
nil
|
||||
(:profile/wallet-accounts db))]
|
||||
(cond
|
||||
(not keycard-match?)
|
||||
(common/show-wrong-keycard-alert cofx)
|
||||
|
||||
(not card-connected?)
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:signing/sign :keycard-step] :signing)}
|
||||
(common/set-on-card-connected :keycard/sign))
|
||||
|
||||
(pos? keycard-pin-retries) ; if 0, get-application-info will have already closed the
|
||||
; connection sheet and opened the frozen card popup
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :card-read-in-progress?] true)
|
||||
(assoc-in [:keycard :pin :status] :verifying))
|
||||
:keycard/sign {:hash (address/naked-address hash)
|
||||
:data data
|
||||
:typed? typed? ; this parameter is for e2e
|
||||
:on-success on-success
|
||||
:pin pin
|
||||
:path path}})))
|
||||
|
||||
(defn normalize-signature
|
||||
[signature]
|
||||
(-> signature
|
||||
(string/replace-first #"00$" "1b")
|
||||
(string/replace-first #"01$" "1c")
|
||||
address/normalized-hex))
|
||||
|
||||
(rf/defn sign-message
|
||||
{:events [:keycard/sign-message]}
|
||||
[cofx params result]
|
||||
(let [{:keys [result error]} (types/json->clj result)
|
||||
on-success #(re-frame/dispatch [:keycard/on-sign-message-success params
|
||||
(normalize-signature %)])
|
||||
hash (address/naked-address result)]
|
||||
(sign cofx hash on-success)))
|
||||
|
||||
(rf/defn on-sign-message-success
|
||||
{:events [:keycard/on-sign-message-success]}
|
||||
[{:keys [db] :as cofx} {:keys [tx-hash message-id chat-id value contract]} signature]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:dispatch
|
||||
(if message-id
|
||||
[:sign/send-accept-transaction-message message-id tx-hash signature]
|
||||
[:sign/send-transaction-message chat-id value contract tx-hash signature])
|
||||
:signing/show-transaction-result nil
|
||||
:db (-> db
|
||||
(assoc-in [:keycard :pin :sign] [])
|
||||
(assoc-in [:keycard :pin :status] nil))}
|
||||
(common/clear-on-card-connected)
|
||||
(common/get-application-info nil)
|
||||
(common/hide-connection-sheet)))
|
||||
|
||||
(rf/defn sign-typed-data
|
||||
{:events [:keycard/sign-typed-data]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-connected? (get-in db [:keycard :card-connected?])
|
||||
hash (get-in db [:keycard :hash])]
|
||||
(if card-connected?
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :card-read-in-progress?] true)
|
||||
(assoc-in [:signing/sign :keycard-step] :signing))
|
||||
:keycard/sign-typed-data {:hash (address/naked-address hash)}}
|
||||
(rf/merge cofx
|
||||
(common/set-on-card-connected :keycard/sign-typed-data)
|
||||
{:db (assoc-in db [:signing/sign :keycard-step] :signing)}))))
|
||||
|
||||
(rf/defn fetch-currency-token-on-success
|
||||
{:events [:keycard/fetch-currency-token-on-success]}
|
||||
[{:keys [db]} {:keys [decimals symbol]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:signing/sign :formatted-data :message :formatted-currency] symbol)
|
||||
(update-in [:signing/sign :formatted-data :message]
|
||||
#(assoc %
|
||||
:formatted-amount
|
||||
(.dividedBy ^js (money/bignumber (:amount %))
|
||||
(money/bignumber (money/from-decimal decimals))))))})
|
||||
|
||||
(rf/defn store-hash-and-sign-typed
|
||||
{:events [:keycard/store-hash-and-sign-typed]}
|
||||
[{:keys [db] :as cofx} result]
|
||||
(let [{:keys [result]} (types/json->clj result)
|
||||
message (get-in db [:signing/sign :formatted-data :message])
|
||||
currency-contract (:currency message)]
|
||||
(when currency-contract
|
||||
{:json-rpc/call [{:method "wallet_discoverToken"
|
||||
:params [(chain/chain-id db) currency-contract]
|
||||
:on-success #(re-frame/dispatch [:keycard/fetch-currency-token-on-success
|
||||
%])}]})
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :hash] result)}
|
||||
sign-typed-data)))
|
||||
|
||||
(rf/defn prepare-to-sign
|
||||
{:events [:keycard/prepare-to-sign]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:on-card-connected :keycard/prepare-to-sign
|
||||
:handler (common/get-application-info :keycard/sign)}))
|
||||
|
||||
(rf/defn sign-message-completed
|
||||
[_ signature]
|
||||
{:dispatch
|
||||
[:signing/sign-message-completed signature]})
|
||||
|
||||
(rf/defn send-transaction-with-signature
|
||||
[_ data]
|
||||
{:send-transaction-with-signature data})
|
||||
|
||||
(rf/defn on-sign-success
|
||||
{:events [:keycard.callback/on-sign-success]}
|
||||
[{:keys [db] :as cofx} signature]
|
||||
(log/debug "[keycard] sign success: " signature)
|
||||
(let [signature-json (types/clj->json {:result (normalize-signature signature)})
|
||||
transaction (get-in db [:keycard :transaction])
|
||||
tx-obj (select-keys transaction
|
||||
[:from :to :value :gas :gasPrice :command? :chat-id :message-id])
|
||||
command? (:command? transaction)]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :hash] nil)
|
||||
(assoc-in [:keycard :transaction] nil))}
|
||||
(when-not command?
|
||||
(fn [{:keys [db] :as cofx}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :sign] [])
|
||||
(assoc-in [:keycard :pin :status] nil))}
|
||||
(common/clear-on-card-connected)
|
||||
(common/get-application-info nil)
|
||||
(common/hide-connection-sheet))))
|
||||
(if transaction
|
||||
(send-transaction-with-signature
|
||||
{:transaction (types/clj->json transaction)
|
||||
:signature signature
|
||||
:on-completed #(re-frame/dispatch [:signing/transaction-completed % tx-obj])})
|
||||
(sign-message-completed signature-json)))))
|
||||
|
||||
(rf/defn on-sign-error
|
||||
{:events [:keycard.callback/on-sign-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[keycard] sign error: " error)
|
||||
(let [tag-was-lost? (common/tag-lost? (:error error))
|
||||
pin-retries (common/pin-retries (:error error))]
|
||||
(when-not tag-was-lost?
|
||||
(if (not (nil? pin-retries))
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
|
||||
(update-in [:keycard :pin]
|
||||
assoc
|
||||
:status :error
|
||||
:sign []
|
||||
:error-label :t/pin-mismatch)
|
||||
(assoc-in [:signing/sign :keycard-step] :pin))}
|
||||
(common/hide-connection-sheet)
|
||||
(when (zero? pin-retries) (common/frozen-keycard-popup)))
|
||||
|
||||
(rf/merge cofx
|
||||
(common/hide-connection-sheet)
|
||||
(common/show-wrong-keycard-alert))))))
|
|
@ -1,588 +0,0 @@
|
|||
(ns legacy.status-im.keycard.simulated-keycard
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[keycard.keycard :as keycard]
|
||||
[legacy.status-im.multiaccounts.create.core :as multiaccounts.create]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[native-module.core :as native-module]
|
||||
re-frame.db
|
||||
[status-im.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as re-frame]))
|
||||
|
||||
(def kk1-password "000000")
|
||||
(def default-pin "111111")
|
||||
(def default-puk "000000000000")
|
||||
(def account-password (native-module/sha3 "no password"))
|
||||
|
||||
(def initial-state
|
||||
{:card-connected? false
|
||||
:application-info {:initialized? false}})
|
||||
|
||||
(defonce state (atom initial-state))
|
||||
|
||||
(defn connect-card
|
||||
[]
|
||||
(swap! state assoc :card-connected? true)
|
||||
(doseq [callback (vals (get @state :on-card-connected))]
|
||||
(callback)))
|
||||
|
||||
(defn connect-selected-card
|
||||
[]
|
||||
(swap! state assoc
|
||||
:application-info
|
||||
{:free-pairing-slots 5
|
||||
:app-version "3.0"
|
||||
:secure-channel-pub-key
|
||||
"04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e"
|
||||
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
|
||||
:paired? true
|
||||
:has-master-key? true
|
||||
:initialized? true
|
||||
:pin-retry-counter 3
|
||||
:puk-retry-counter 5
|
||||
:key-uid (get-in @re-frame.db/app-db [:profile/login :key-uid])})
|
||||
(swap! state assoc :pin default-pin :puk default-puk :password kk1-password)
|
||||
(connect-card))
|
||||
|
||||
(def initialization (atom false))
|
||||
|
||||
(defn connect-pairing-card
|
||||
[]
|
||||
(reset! initialization false)
|
||||
(swap! state assoc
|
||||
:application-info
|
||||
{:free-pairing-slots 5
|
||||
:app-version "3.0"
|
||||
:secure-channel-pub-key
|
||||
"04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e"
|
||||
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
|
||||
:paired? false
|
||||
:has-master-key? true
|
||||
:initialized? true
|
||||
:pin-retry-counter 3
|
||||
:puk-retry-counter 5
|
||||
:key-uid "0x16839e8b1b8a395acb18100c7e2b161701c225adf31eefa02114099b4d81a30b"})
|
||||
(swap! state assoc :pin default-pin :puk default-puk :password kk1-password)
|
||||
(connect-card))
|
||||
|
||||
(defn disconnect-card
|
||||
[]
|
||||
(swap! state assoc :card-connected? false)
|
||||
(doseq [callback (vals (get @state :on-card-disconnected))]
|
||||
(callback)))
|
||||
|
||||
(defn reset-state
|
||||
[]
|
||||
(swap! state assoc :application-info {:initialized? false}))
|
||||
|
||||
(defn- later
|
||||
[f]
|
||||
(when f (js/setTimeout f 500)))
|
||||
|
||||
(defn pin-error
|
||||
[]
|
||||
#js
|
||||
{:code "EUNSPECIFIED"
|
||||
:message (str "Unexpected error SW, 0x63C" (get-in @state [:application-info :pin-retry-counter]))})
|
||||
|
||||
(defn puk-error
|
||||
[]
|
||||
#js
|
||||
{:code "EUNSPECIFIED"
|
||||
:message (str "Unexpected error SW, 0x63C" (get-in @state [:application-info :puk-retry-counter]))})
|
||||
|
||||
(defn with-pin
|
||||
[pin on-failure on-valid]
|
||||
(cond
|
||||
(= (get-in @state [:application-info :pin-retry-counter]) 0)
|
||||
(later #(on-failure (pin-error)))
|
||||
|
||||
(= pin (get @state :pin))
|
||||
(do
|
||||
(swap! state update
|
||||
:application-info assoc
|
||||
:pin-retry-counter 3
|
||||
:puk-retry-counter 5)
|
||||
(later on-valid))
|
||||
|
||||
:else
|
||||
(do
|
||||
(swap! state update-in
|
||||
[:application-info :pin-retry-counter]
|
||||
(fnil dec 3))
|
||||
(later #(on-failure (pin-error))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn start-nfc
|
||||
[{:keys [on-success]}]
|
||||
(when (get @state :card-connected?) (connect-card))
|
||||
(later #(on-success true)))
|
||||
|
||||
(defn stop-nfc
|
||||
[{:keys [on-success]}]
|
||||
(later #(on-success true)))
|
||||
|
||||
(defn set-nfc-message
|
||||
[{:keys [on-success]}]
|
||||
(later #(on-success true)))
|
||||
|
||||
(defn check-nfc-support
|
||||
[{:keys [on-success]}]
|
||||
(later #(on-success true)))
|
||||
|
||||
(defn check-nfc-enabled
|
||||
[{:keys [on-success]}]
|
||||
(later #(on-success true)))
|
||||
|
||||
(defn open-nfc-settings [])
|
||||
|
||||
(defn on-card-connected
|
||||
[callback]
|
||||
(let [id (random-uuid)]
|
||||
(swap! state update :on-card-connected assoc id callback)
|
||||
id))
|
||||
|
||||
(defn on-card-disconnected
|
||||
[callback]
|
||||
(let [id (random-uuid)]
|
||||
(swap! state update :on-card-disconnected assoc id callback)
|
||||
id))
|
||||
|
||||
(defn register-card-events
|
||||
[args]
|
||||
(log/debug "register-card-events")
|
||||
(on-card-connected (:on-card-connected args))
|
||||
(on-card-disconnected (:on-card-disconnected args)))
|
||||
|
||||
(defn set-pairings
|
||||
[args]
|
||||
(log/warn "set-pairings not implemented" args))
|
||||
|
||||
(defn remove-event-listener
|
||||
[id]
|
||||
(log/debug "remove-event-listener")
|
||||
(swap! state update :on-card-connected dissoc id)
|
||||
(swap! state update :on-card-disconnected dissoc id))
|
||||
|
||||
(defn remove-event-listeners
|
||||
[]
|
||||
(log/debug "remove-event-listeners")
|
||||
(swap! state dissoc :on-card-connected)
|
||||
(swap! state dissoc :on-card-disconnected))
|
||||
|
||||
(defn get-application-info
|
||||
[{:keys [on-success]}]
|
||||
(log/debug "get-application-info")
|
||||
(later #(on-success (get @state :application-info))))
|
||||
|
||||
(defn factory-reset
|
||||
[args]
|
||||
(log/debug "factory-reset")
|
||||
(reset-state)
|
||||
(get-application-info args))
|
||||
|
||||
(defn install-applet [_])
|
||||
(defn install-cash-applet [_])
|
||||
|
||||
(defn init-card
|
||||
[{:keys [pin on-success]}]
|
||||
(reset! initialization true)
|
||||
(swap! state assoc
|
||||
:application-info
|
||||
{:free-pairing-slots 5
|
||||
:app-version "3.0"
|
||||
:secure-channel-pub-key
|
||||
"04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e"
|
||||
:key-uid ""
|
||||
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
|
||||
:paired? false
|
||||
:has-master-key? false
|
||||
:pin-retry-counter 3
|
||||
:puk-retry-counter 5
|
||||
:initialized? true})
|
||||
(swap! state assoc :pin pin :puk default-puk :password kk1-password)
|
||||
(later
|
||||
#(on-success {:password kk1-password
|
||||
:puk default-puk
|
||||
:pin pin})))
|
||||
|
||||
(defn install-applet-and-init-card [_])
|
||||
|
||||
(def derived-acc (atom nil))
|
||||
|
||||
(defn multiaccount->keys
|
||||
[data]
|
||||
(let [{:keys [selected-id multiaccounts root-key derived]}
|
||||
data
|
||||
|
||||
{:keys [id address public-key derived key-uid]}
|
||||
(or (->> multiaccounts
|
||||
(filter #(= (:id %) selected-id))
|
||||
first)
|
||||
(assoc root-key :derived derived))
|
||||
|
||||
whisper (get derived constants/path-whisper-keyword)
|
||||
wallet (get derived constants/path-default-wallet-keyword)
|
||||
wallet-root (get derived constants/path-wallet-root-keyword)
|
||||
password account-password
|
||||
response {:key-uid key-uid
|
||||
:encryption-public-key password
|
||||
: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)}]
|
||||
[id response]))
|
||||
|
||||
(defn pair
|
||||
[{:keys [password on-success]}]
|
||||
(when (and (not @initialization)
|
||||
(not @derived-acc))
|
||||
(native-module/multiaccount-import-mnemonic
|
||||
"night fortune spider version version armed amused winner matter tonight cave flag"
|
||||
nil
|
||||
(fn [result]
|
||||
(let [{:keys [id] :as root-data}
|
||||
(multiaccounts.create/normalize-multiaccount-data-keys
|
||||
(types/json->clj result))]
|
||||
(native-module.core/multiaccount-derive-addresses
|
||||
id
|
||||
[constants/path-wallet-root
|
||||
constants/path-eip1581
|
||||
constants/path-whisper
|
||||
constants/path-default-wallet]
|
||||
(fn [result]
|
||||
(let [derived-data (multiaccounts.create/normalize-derived-data-keys
|
||||
(types/json->clj result))]
|
||||
(reset! derived-acc
|
||||
{:root-key root-data
|
||||
:derived derived-data}))))))))
|
||||
(when (= password (get @state :password))
|
||||
(swap! state assoc-in [:application-info :paired?] true)
|
||||
(later #(on-success (str (rand-int 10000000))))))
|
||||
|
||||
(defn generate-and-load-key
|
||||
[{:keys [pin on-success key-uid delete-multiaccount?]}]
|
||||
(when (= pin (get @state :pin))
|
||||
(let [[id response] (multiaccount->keys
|
||||
(:intro-wizard @re-frame.db/app-db))]
|
||||
(log/debug "[simulated kk] generate-and-load-key response" response)
|
||||
(swap! state assoc-in
|
||||
[:application-info :key-uid]
|
||||
(:key-uid response))
|
||||
(let [deletion-wrapper
|
||||
(if delete-multiaccount?
|
||||
(fn [on-deletion-success]
|
||||
(js/alert "OH SHEET")
|
||||
(native-module/delete-multiaccount
|
||||
key-uid
|
||||
(fn [result]
|
||||
(let [{:keys [error]} (types/json->clj result)]
|
||||
(if-not (string/blank? error)
|
||||
(log/error error)
|
||||
(on-deletion-success))))))
|
||||
(fn [cb] (cb)))]
|
||||
(deletion-wrapper
|
||||
(fn []
|
||||
(native-module/multiaccount-store-derived
|
||||
id
|
||||
(:key-uid response)
|
||||
[constants/path-wallet-root
|
||||
constants/path-eip1581
|
||||
constants/path-whisper
|
||||
constants/path-default-wallet]
|
||||
account-password
|
||||
#(on-success response))))))))
|
||||
|
||||
(defn unblock-pin
|
||||
[{:keys [puk new-pin on-success on-failure]}]
|
||||
(cond
|
||||
(= (get-in @state [:application-info :puk-retry-counter]) 0)
|
||||
(later #(on-failure (puk-error)))
|
||||
|
||||
(= puk (get @state :puk))
|
||||
(do
|
||||
(swap! state update
|
||||
:application-info assoc
|
||||
:pin-retry-counter 3
|
||||
:puk-retry-counter 5)
|
||||
(swap! state assoc :pin new-pin)
|
||||
(later #(on-success true)))
|
||||
|
||||
:else
|
||||
(do
|
||||
(swap! state update-in
|
||||
[:application-info :puk-retry-counter]
|
||||
(fnil dec 5))
|
||||
(later
|
||||
#(on-failure (puk-error))))))
|
||||
|
||||
(defn verify-pin
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(with-pin pin on-failure #(on-success 3)))
|
||||
|
||||
(defn change-pin
|
||||
[{:keys [current-pin new-pin on-success on-failure]}]
|
||||
(with-pin current-pin
|
||||
on-failure
|
||||
(fn []
|
||||
(swap! state assoc :pin new-pin)
|
||||
(on-success))))
|
||||
|
||||
(defn change-puk
|
||||
[{:keys [pin puk on-success on-failure]}]
|
||||
(with-pin pin
|
||||
on-failure
|
||||
(fn []
|
||||
(swap! state assoc :puk puk)
|
||||
(on-success))))
|
||||
|
||||
(defn change-pairing
|
||||
[{:keys [pin pairing on-success on-failure]}]
|
||||
(with-pin pin
|
||||
on-failure
|
||||
(fn []
|
||||
(swap! state assoc :password pairing)
|
||||
(on-success))))
|
||||
|
||||
(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]}]
|
||||
(with-pin
|
||||
pin
|
||||
on-failure
|
||||
#(let [{:keys [key-uid wallet-root-address]}
|
||||
(get @re-frame.db/app-db :profile/profile)
|
||||
accounts (get @re-frame.db/app-db :profile/wallet-accounts)
|
||||
hashed-password account-password
|
||||
path-num (inc (get-in @re-frame.db/app-db
|
||||
[:profile/profile :latest-derived-path]))
|
||||
path (str "m/" path-num)]
|
||||
(native-module/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])
|
||||
(native-module/multiaccount-derive-addresses
|
||||
id
|
||||
[path]
|
||||
(fn [derived]
|
||||
(let [derived-address (get-in (types/json->clj derived) [(keyword path) :address])]
|
||||
(if (some (fn [a] (= derived-address (get a :address))) accounts)
|
||||
(re-frame/dispatch [::new-account-error :account-error
|
||||
(i18n/label :t/account-exists-title)])
|
||||
(native-module/multiaccount-store-derived
|
||||
id
|
||||
key-uid
|
||||
[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 on-failure pin]}]
|
||||
(with-pin pin
|
||||
on-failure
|
||||
(if @derived-acc
|
||||
(let [[id account-keys] (multiaccount->keys @derived-acc)]
|
||||
(swap! state assoc-in
|
||||
[:application-info :key-uid]
|
||||
(:key-uid account-keys))
|
||||
(native-module/multiaccount-store-derived
|
||||
id
|
||||
(:key-uid account-keys)
|
||||
[constants/path-wallet-root
|
||||
constants/path-eip1581
|
||||
constants/path-whisper
|
||||
constants/path-default-wallet]
|
||||
account-password
|
||||
#(on-success account-keys)))
|
||||
#(on-success
|
||||
{:key-uid (get-in @state [:application-info :key-uid])
|
||||
:instance-uid (get-in @state [:application-info :instance-uid])
|
||||
:encryption-public-key account-password}))))
|
||||
|
||||
(def import-keys get-keys)
|
||||
|
||||
(defn sign
|
||||
[{:keys [pin data path typed? on-success on-failure] :as card}]
|
||||
(with-pin pin
|
||||
on-failure
|
||||
#(let [address
|
||||
(if path
|
||||
(reduce
|
||||
(fn [_ {:keys [address] :as acc}]
|
||||
(when (= path (:path acc))
|
||||
(reduced address)))
|
||||
nil
|
||||
(:profile/wallet-accounts @re-frame.db/app-db))
|
||||
(-> (:profile/wallet-accounts @re-frame.db/app-db)
|
||||
first
|
||||
:address))
|
||||
password account-password]
|
||||
(if-not typed?
|
||||
(let [params (types/clj->json
|
||||
{:account address
|
||||
:password password
|
||||
:data (or data (str "0x" (:hash card)))})]
|
||||
(native-module/sign-message
|
||||
params
|
||||
(fn [res]
|
||||
(let [signature (-> res
|
||||
types/json->clj
|
||||
:result
|
||||
address/normalized-hex)]
|
||||
(on-success signature)))))
|
||||
(native-module/sign-typed-data
|
||||
data
|
||||
address
|
||||
password
|
||||
(fn [res]
|
||||
(let [signature (-> res
|
||||
types/json->clj
|
||||
:result
|
||||
address/normalized-hex)]
|
||||
(on-success signature))))))))
|
||||
|
||||
(defn sign-typed-data
|
||||
[args]
|
||||
(log/warn "sign-typed-data not implemented" args))
|
||||
|
||||
(defrecord SimulatedKeycard []
|
||||
keycard/Keycard
|
||||
(keycard/start-nfc [_this args]
|
||||
(log/debug "simulated card start-nfc")
|
||||
(start-nfc args))
|
||||
(keycard/stop-nfc [_this args]
|
||||
(log/debug "simulated card stop-nfc")
|
||||
(stop-nfc args))
|
||||
(keycard/set-nfc-message [_this args]
|
||||
(log/debug "simulated card set-nfc-message")
|
||||
(set-nfc-message args))
|
||||
(keycard/check-nfc-support [_this args]
|
||||
(log/debug "simulated card check-nfc-support")
|
||||
(check-nfc-support args))
|
||||
(keycard/check-nfc-enabled [_this args]
|
||||
(log/debug "simulated card check-nfc-enabled")
|
||||
(check-nfc-enabled args))
|
||||
(keycard/open-nfc-settings [_this]
|
||||
(log/debug "simulated card open-nfc-setting")
|
||||
(open-nfc-settings))
|
||||
(keycard/register-card-events [_this args]
|
||||
(log/debug "simulated card register-card-event")
|
||||
(register-card-events args))
|
||||
(keycard/set-pairings [_this args]
|
||||
(log/debug "simulated card set-pairings")
|
||||
(set-pairings args))
|
||||
(keycard/on-card-connected [_this callback]
|
||||
(log/debug "simulated card on-card-connected")
|
||||
(on-card-connected callback))
|
||||
(keycard/on-card-disconnected [_this callback]
|
||||
(log/debug "simulated card on-card-disconnected")
|
||||
(on-card-disconnected callback))
|
||||
(keycard/remove-event-listener [_this event]
|
||||
(log/debug "simulated card remove-event-listener")
|
||||
(remove-event-listener event))
|
||||
(keycard/remove-event-listeners [_this]
|
||||
(log/debug "simulated card remove-event-listener")
|
||||
(remove-event-listeners))
|
||||
(keycard/get-application-info [_this args]
|
||||
(log/debug "simulated card get-application-info")
|
||||
(get-application-info args))
|
||||
(keycard/factory-reset [_this args]
|
||||
(log/debug "simulated card factory-reset")
|
||||
(factory-reset args))
|
||||
(keycard/install-applet [_this args]
|
||||
(log/debug "simulated card install-applet")
|
||||
(install-applet args))
|
||||
(keycard/init-card [_this args]
|
||||
(log/debug "simulated card init-card")
|
||||
(init-card args))
|
||||
(keycard/install-applet-and-init-card [_this args]
|
||||
(log/debug "simulated card install-applet-and-init-card")
|
||||
(install-applet-and-init-card args))
|
||||
(keycard/pair [_this args]
|
||||
(log/debug "simulated card pair")
|
||||
(pair args))
|
||||
(keycard/generate-and-load-key [_this args]
|
||||
(log/debug "simulated card generate-and-load-key")
|
||||
(generate-and-load-key args))
|
||||
(keycard/unblock-pin [_this args]
|
||||
(log/debug "simulated card unblock-pin")
|
||||
(unblock-pin args))
|
||||
(keycard/verify-pin [_this args]
|
||||
(log/debug "simulated card verify-pin")
|
||||
(verify-pin args))
|
||||
(keycard/change-pin [_this args]
|
||||
(log/debug "simulated card change-pin")
|
||||
(change-pin args))
|
||||
(keycard/change-puk [_this args]
|
||||
(log/debug "simulated card change-puk")
|
||||
(change-puk args))
|
||||
(keycard/change-pairing [_this args]
|
||||
(log/debug "simulated card change-pairing")
|
||||
(change-pairing args))
|
||||
(keycard/unpair [_this args]
|
||||
(log/debug "simulated card unpair")
|
||||
(unpair args))
|
||||
(keycard/delete [_this args]
|
||||
(log/debug "simulated card delete")
|
||||
(delete args))
|
||||
(keycard/remove-key [_this args]
|
||||
(log/debug "simulated card remove-key")
|
||||
(remove-key args))
|
||||
(keycard/remove-key-with-unpair [_this args]
|
||||
(log/debug "simulated card remove-key-with-unpair")
|
||||
(remove-key-with-unpair args))
|
||||
(keycard/export-key [_this args]
|
||||
(log/debug "simulated card export-key")
|
||||
(export-key args))
|
||||
(keycard/unpair-and-delete [_this args]
|
||||
(log/debug "simulated card unpair-and-delete")
|
||||
(unpair-and-delete args))
|
||||
(keycard/import-keys [_this args]
|
||||
(log/debug "simulated card import-keys")
|
||||
(import-keys args))
|
||||
(keycard/get-keys [_this args]
|
||||
(log/debug "simulated card get-keys")
|
||||
(get-keys args))
|
||||
(keycard/sign [_this args]
|
||||
(log/debug "simulated card sign")
|
||||
(sign args)))
|
|
@ -1,32 +0,0 @@
|
|||
(ns legacy.status-im.keycard.test-menu
|
||||
(:require
|
||||
[legacy.status-im.keycard.simulated-keycard :as simulated-keycard]
|
||||
[legacy.status-im.ui.components.react :as react]))
|
||||
|
||||
(defn button
|
||||
[label accessibility-label handler]
|
||||
[react/view
|
||||
{:style {:width 20
|
||||
:height 30
|
||||
:justify-content :center
|
||||
:align-items :center}}
|
||||
[react/text
|
||||
{:on-press handler
|
||||
:style {:font-size 8}
|
||||
:accessibility-label accessibility-label}
|
||||
label]])
|
||||
|
||||
(defn test-menu
|
||||
[]
|
||||
[react/view
|
||||
{:style {:position :absolute
|
||||
:top 70
|
||||
:right 0
|
||||
:width 50
|
||||
:justify-content :center
|
||||
:align-items :center}}
|
||||
[button "conn" :connect-card simulated-keycard/connect-card]
|
||||
[button "conn sell" :connect-selected-card simulated-keycard/connect-selected-card]
|
||||
[button "pair" :connect-pairing-card simulated-keycard/connect-pairing-card]
|
||||
[button "disc" :disconnect-card simulated-keycard/disconnect-card]
|
||||
[button "res" :keycard-reset-state simulated-keycard/reset-state]])
|
|
@ -1,187 +0,0 @@
|
|||
(ns legacy.status-im.keycard.unpair
|
||||
(:require
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn unpair-card-pressed
|
||||
{:events [:keycard-settings.ui/unpair-card-pressed]}
|
||||
[_]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/unpair-card)
|
||||
:content (i18n/label :t/unpair-card-confirmation)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/no)
|
||||
:on-accept #(re-frame/dispatch
|
||||
[:keycard-settings.ui/unpair-card-confirmed])
|
||||
:on-cancel #()}})
|
||||
|
||||
(rf/defn unpair-card-confirmed
|
||||
{:events [:keycard-settings.ui/unpair-card-confirmed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:enter-step :current
|
||||
:current []
|
||||
:puk []
|
||||
:status nil
|
||||
:error-label nil
|
||||
:on-verified :keycard/unpair})}
|
||||
(common/navigate-to-enter-pin-screen)))
|
||||
|
||||
(rf/defn unpair
|
||||
{:events [:keycard/unpair]}
|
||||
[{:keys [db]}]
|
||||
(let [pin (common/vector->string (get-in db [:keycard :pin :current]))]
|
||||
{:keycard/unpair {:pin pin}}))
|
||||
|
||||
(rf/defn unpair-and-delete
|
||||
{:events [:keycard/unpair-and-delete]}
|
||||
[cofx]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:on-card-connected :keycard/unpair-and-delete
|
||||
:handler
|
||||
(fn [{:keys [db]}]
|
||||
(let [pin (common/vector->string (get-in db [:keycard :pin :current]))]
|
||||
{:keycard/unpair-and-delete
|
||||
{:pin pin}}))}))
|
||||
|
||||
(rf/defn remove-pairing-from-multiaccount
|
||||
[cofx {:keys [remove-instance-uid?]}]
|
||||
(rf/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:keycard-pairing
|
||||
nil
|
||||
{})
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:keycard-paired-on
|
||||
nil
|
||||
{})
|
||||
(when remove-instance-uid?
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:keycard-instance-uid
|
||||
nil
|
||||
{}))))
|
||||
|
||||
(rf/defn on-unpair-success
|
||||
{:events [:keycard.callback/on-unpair-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [instance-uid (get-in db [:keycard :application-info :instance-uid])
|
||||
pairings (get-in db [:keycard :pairings])]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :secrets] nil)
|
||||
(update-in [:keycard :pairings] dissoc (keyword instance-uid))
|
||||
(assoc-in [:keycard :pin]
|
||||
{:status nil
|
||||
:error-label nil
|
||||
:on-verified nil}))
|
||||
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/card-unpaired)}}
|
||||
(common/clear-on-card-connected)
|
||||
(remove-pairing-from-multiaccount nil)
|
||||
(navigation/navigate-to :keycard-settings nil))))
|
||||
|
||||
(rf/defn on-unpair-error
|
||||
{:events [:keycard.callback/on-unpair-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[keycard] unpair error" error)
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:error-label nil
|
||||
:on-verified nil})
|
||||
:keycard/get-application-info nil
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/something-went-wrong)}}
|
||||
(common/clear-on-card-connected)
|
||||
(navigation/navigate-to :keycard-settings nil)))
|
||||
|
||||
(rf/defn remove-key-with-unpair
|
||||
{:events [:keycard/remove-key-with-unpair]}
|
||||
[cofx]
|
||||
(common/show-connection-sheet
|
||||
cofx
|
||||
{:on-card-connected :keycard/remove-key-with-unpair
|
||||
:handler
|
||||
(fn [{:keys [db]}]
|
||||
(let [pin (common/vector->string (get-in db [:keycard :pin :current]))]
|
||||
{:keycard/remove-key-with-unpair
|
||||
{:pin pin}}))}))
|
||||
|
||||
(defn handle-account-removal
|
||||
[{:keys [db] :as cofx} keys-removed-from-card?]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
instance-uid (get-in db [:keycard :application-info :instance-uid])
|
||||
pairings (get-in db [:keycard :pairings])]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(update :profile/profiles-overview dissoc key-uid)
|
||||
(assoc-in [:keycard :secrets] nil)
|
||||
(update-in [:keycard :pairings]
|
||||
dissoc
|
||||
(keyword instance-uid))
|
||||
(update-in [:keycard :pairings] dissoc instance-uid)
|
||||
(assoc-in [:keycard :whisper-public-key] nil)
|
||||
(assoc-in [:keycard :wallet-address] nil)
|
||||
(assoc-in [:keycard :application-info] nil)
|
||||
(assoc-in [:keycard :pin]
|
||||
{:status nil
|
||||
:error-label nil
|
||||
:on-verified nil}))
|
||||
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
|
||||
:effects.utils/show-popup {:title (i18n/label (if keys-removed-from-card?
|
||||
:t/profile-deleted-title
|
||||
:t/database-reset-title))
|
||||
:content (i18n/label (if keys-removed-from-card?
|
||||
:t/profile-deleted-keycard
|
||||
:t/database-reset-content))
|
||||
:on-dismiss #(re-frame/dispatch [:logout])}}
|
||||
;;should be reimplemented :key-storage/delete-profile {:key-uid key-uid
|
||||
;;:on-success #(log/debug "[keycard] remove account ok")
|
||||
;; :on-error #(log/warn "[keycard] remove account: " %)}
|
||||
(common/clear-on-card-connected)
|
||||
(common/hide-connection-sheet))))
|
||||
|
||||
(rf/defn on-remove-key-success
|
||||
{:events [:keycard.callback/on-remove-key-success]}
|
||||
[cofx]
|
||||
(handle-account-removal cofx true))
|
||||
|
||||
(rf/defn on-remove-key-error
|
||||
{:events [:keycard.callback/on-remove-key-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[keycard] remove key error" error)
|
||||
(let [tag-was-lost? (common/tag-lost? (:error error))]
|
||||
(rf/merge cofx
|
||||
(if tag-was-lost?
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(common/set-on-card-connected :keycard/remove-key-with-unpair))
|
||||
(common/show-wrong-keycard-alert)))))
|
||||
|
||||
(rf/defn on-unpair-and-delete-success
|
||||
{:events [:keycard.callback/on-unpair-and-delete-success]}
|
||||
[cofx]
|
||||
(handle-account-removal cofx false))
|
||||
|
||||
(rf/defn on-unpair-and-delete-error
|
||||
{:events [:keycard.callback/on-unpair-and-delete-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[keycard] unpair and delete error" error)
|
||||
(let [tag-was-lost? (common/tag-lost? (:error error))]
|
||||
(rf/merge cofx
|
||||
(if tag-was-lost?
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(common/set-on-card-connected :keycard/unpair-and-delete))
|
||||
(common/show-wrong-keycard-alert)))))
|
|
@ -5,16 +5,6 @@
|
|||
[react-native.platform :as platform]
|
||||
[status-im.config :as config]))
|
||||
|
||||
(defn- add-custom-bootnodes
|
||||
[config network all-bootnodes]
|
||||
(let [bootnodes (as-> all-bootnodes $
|
||||
(get $ network)
|
||||
(vals $)
|
||||
(map :address $))]
|
||||
(if (seq bootnodes)
|
||||
(assoc-in config [:ClusterConfig :BootNodes] bootnodes)
|
||||
config)))
|
||||
|
||||
(defn- add-log-level
|
||||
[config log-level]
|
||||
(if (empty? log-level)
|
||||
|
@ -124,10 +114,8 @@
|
|||
waku-nodes (get config/waku-nodes-config fleet-key)
|
||||
rendezvous-nodes (pick-nodes 3 (vals (:rendezvous current-fleet)))
|
||||
{:keys [installation-id log-level
|
||||
waku-bloom-filter-mode
|
||||
custom-bootnodes custom-bootnodes-enabled?]}
|
||||
profile
|
||||
use-custom-bootnodes (get custom-bootnodes-enabled? current-network)]
|
||||
waku-bloom-filter-mode]}
|
||||
profile]
|
||||
(cond-> (get-in networks [current-network :config])
|
||||
:always
|
||||
(get-base-node-config)
|
||||
|
@ -144,8 +132,6 @@
|
|||
(if wakuv2-enabled
|
||||
waku-nodes
|
||||
[])
|
||||
:BootNodes
|
||||
(if wakuv2-enabled [] (pick-nodes 4 (vals (:boot current-fleet))))
|
||||
:TrustedMailServers
|
||||
(if wakuv2-enabled [] (pick-nodes 6 (vals (:mail current-fleet))))
|
||||
:StaticNodes
|
||||
|
@ -185,11 +171,6 @@
|
|||
:RequireTopics (get-topics current-network)
|
||||
:StatusAccountsConfig {:Enabled true})
|
||||
|
||||
(and
|
||||
config/bootnodes-settings-enabled?
|
||||
use-custom-bootnodes)
|
||||
(add-custom-bootnodes current-network custom-bootnodes)
|
||||
|
||||
:always
|
||||
(add-log-level log-level))))
|
||||
|
||||
|
|
|
@ -1,650 +0,0 @@
|
|||
(ns legacy.status-im.signing.core
|
||||
(:require
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.ethereum.tokens :as tokens]
|
||||
[legacy.status-im.keycard.card :as keycard.card]
|
||||
[legacy.status-im.keycard.common :as keycard.common]
|
||||
[legacy.status-im.signing.eip1559 :as eip1559]
|
||||
[legacy.status-im.signing.keycard :as signing.keycard]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[legacy.status-im.utils.hex :as utils.hex]
|
||||
[legacy.status-im.utils.utils :as utils]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.ethereum.eip.eip55 :as eip55]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing/send-transaction-fx
|
||||
(fn [{:keys [tx-obj hashed-password cb]}]
|
||||
(native-module/send-transaction (types/clj->json tx-obj)
|
||||
hashed-password
|
||||
cb)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing/show-transaction-error
|
||||
(fn [message]
|
||||
(utils/show-popup (i18n/label :t/transaction-failed) message)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing/show-transaction-result
|
||||
(fn []
|
||||
(utils/show-popup (i18n/label :t/transaction-sent) (i18n/label :t/transaction-description))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing.fx/sign-message
|
||||
(fn [{:keys [params on-completed]}]
|
||||
(native-module/sign-message (types/clj->json params)
|
||||
on-completed)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing.fx/recover-message
|
||||
(fn [{:keys [params on-completed]}]
|
||||
(native-module/recover-message (types/clj->json params)
|
||||
on-completed)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing.fx/sign-typed-data
|
||||
(fn [{:keys [v4 data account on-completed hashed-password]}]
|
||||
(if v4
|
||||
(native-module/sign-typed-data-v4 data account hashed-password on-completed)
|
||||
(native-module/sign-typed-data data account hashed-password on-completed))))
|
||||
|
||||
(defn get-contact
|
||||
[db to]
|
||||
(let [to (utils.hex/normalize-hex to)]
|
||||
(or
|
||||
(get-in db [:contacts/contacts to])
|
||||
{:address (address/normalized-hex to)})))
|
||||
|
||||
(rf/defn change-password
|
||||
{:events [:signing.ui/password-is-changed]}
|
||||
[{db :db} password]
|
||||
(let [unmasked-pass (security/safe-unmask-data password)]
|
||||
{:db (update db
|
||||
:signing/sign assoc
|
||||
:password password
|
||||
:error nil
|
||||
:enabled? (and unmasked-pass (> (count unmasked-pass) 5)))}))
|
||||
|
||||
(rf/defn sign-message
|
||||
[{{:signing/keys [sign tx] :as db} :db}]
|
||||
(let [{{:keys [data typed? from v4]} :message} tx
|
||||
{:keys [in-progress? password]} sign
|
||||
from from
|
||||
hashed-password (native-module/sha3 (security/safe-unmask-data
|
||||
password))]
|
||||
(when-not in-progress?
|
||||
(merge
|
||||
{:db (update db :signing/sign assoc :error nil :in-progress? true)}
|
||||
(if typed?
|
||||
{:signing.fx/sign-typed-data {:v4 v4
|
||||
:data data
|
||||
:account from
|
||||
:hashed-password hashed-password
|
||||
:on-completed #(re-frame/dispatch
|
||||
[:signing/sign-message-completed %])}}
|
||||
{:signing.fx/sign-message {:params {:data data
|
||||
:password hashed-password
|
||||
:account from}
|
||||
:on-completed #(re-frame/dispatch [:signing/sign-message-completed
|
||||
%])}})))))
|
||||
|
||||
(rf/defn send-transaction
|
||||
{:events [:signing.ui/sign-is-pressed]}
|
||||
[{{:signing/keys [sign tx] :ens/keys [registration] :as db} :db :as cofx}]
|
||||
(let [{:keys [in-progress? password]} sign
|
||||
{:keys [tx-obj gas gasPrice maxPriorityFeePerGas
|
||||
maxFeePerGas message nonce]} tx
|
||||
hashed-password (native-module/sha3 (security/safe-unmask-data
|
||||
password))
|
||||
{:keys [action username custom-domain?]} registration
|
||||
{:keys [public-key]} (:profile/profile db)
|
||||
chain-id (chain/chain-id db)]
|
||||
(if message
|
||||
(sign-message cofx)
|
||||
(let [tx-obj-to-send (merge tx-obj
|
||||
(when gas
|
||||
{:gas (str "0x" (native-module/number-to-hex gas))})
|
||||
(when gasPrice
|
||||
{:gasPrice (str "0x" (native-module/number-to-hex gasPrice))})
|
||||
(when nonce
|
||||
{:nonce (str "0x" (native-module/number-to-hex nonce))})
|
||||
(when maxPriorityFeePerGas
|
||||
{:maxPriorityFeePerGas (str "0x"
|
||||
(native-module/number-to-hex
|
||||
(js/parseInt maxPriorityFeePerGas)))})
|
||||
(when maxFeePerGas
|
||||
{:maxFeePerGas (str "0x"
|
||||
(native-module/number-to-hex
|
||||
(js/parseInt maxFeePerGas)))}))
|
||||
cb #(re-frame/dispatch
|
||||
[:signing/transaction-completed %
|
||||
tx-obj-to-send hashed-password])
|
||||
watch-ens-tx-fn #(re-frame/dispatch
|
||||
[:transactions/watch-transaction
|
||||
%
|
||||
{:trigger-fn
|
||||
(fn [_ {:keys [hash type]}]
|
||||
(and (= hash %)
|
||||
(contains? #{:outbound :failed} type)))
|
||||
:on-trigger
|
||||
(fn [{:keys [type]}]
|
||||
(case type
|
||||
:outbound (do (rf/dispatch [:ens/clear-registration %])
|
||||
(rf/dispatch [:ens/save-username custom-domain?
|
||||
username false]))
|
||||
|
||||
:failed (rf/dispatch [:ens/update-ens-tx-state :failure username
|
||||
custom-domain? %])
|
||||
nil))}])]
|
||||
(when-not in-progress?
|
||||
(cond-> {:db (update db :signing/sign assoc :error nil :in-progress? true)}
|
||||
(nil? action) (assoc :signing/send-transaction-fx
|
||||
{:tx-obj tx-obj-to-send
|
||||
:hashed-password hashed-password
|
||||
:cb cb})
|
||||
(= action constants/ens-action-type-register) (assoc :json-rpc/call
|
||||
[{:method "ens_register"
|
||||
:params [chain-id tx-obj-to-send
|
||||
hashed-password username
|
||||
public-key]
|
||||
:on-success
|
||||
#(do
|
||||
(cb (types/clj->json
|
||||
{:result %}))
|
||||
(watch-ens-tx-fn %))
|
||||
:on-error #(cb (types/clj->json
|
||||
{:error %}))}])
|
||||
(= action
|
||||
constants/ens-action-type-set-pub-key) (assoc :json-rpc/call
|
||||
[{:method "ens_setPubKey"
|
||||
:params [chain-id tx-obj-to-send
|
||||
hashed-password username
|
||||
public-key]
|
||||
:on-success #(do (cb (types/clj->json
|
||||
{:result %}))
|
||||
(watch-ens-tx-fn %))
|
||||
:on-error #(cb (types/clj->json
|
||||
{:error
|
||||
%}))}])))))))
|
||||
|
||||
(rf/defn prepare-unconfirmed-transaction
|
||||
[{:keys [db now]} new-tx-hash
|
||||
{:keys [value gasPrice maxFeePerGas maxPriorityFeePerGas gas data to from hash]} symbol amount]
|
||||
(let [token (tokens/symbol->token (:wallet-legacy/all-tokens db) symbol)
|
||||
from (eip55/address->checksum from)
|
||||
;;if there is a hash in the tx object that means we resending transaction
|
||||
old-tx-hash hash
|
||||
gas-price (money/to-fixed (money/bignumber gasPrice))
|
||||
gas-limit (money/to-fixed (money/bignumber gas))
|
||||
tx {:timestamp now
|
||||
:to to
|
||||
:from from
|
||||
:type :pending
|
||||
:hash new-tx-hash
|
||||
:data data
|
||||
:token token
|
||||
:symbol symbol
|
||||
:value (if token
|
||||
(money/to-fixed (money/unit->token amount (:decimals token)))
|
||||
(money/to-fixed (money/bignumber value)))
|
||||
:gas-price gas-price
|
||||
:fee-cap maxFeePerGas
|
||||
:tip-cap maxPriorityFeePerGas
|
||||
:gas-limit gas-limit}]
|
||||
(log/info "[signing] prepare-unconfirmed-transaction" tx)
|
||||
{:db (-> db
|
||||
;;remove old transaction, because we replace it with the new one
|
||||
(update-in [:wallet-legacy :accounts from :transactions] dissoc old-tx-hash)
|
||||
(assoc-in [:wallet-legacy :accounts from :transactions new-tx-hash] tx))}))
|
||||
|
||||
(defn get-method-type
|
||||
[data]
|
||||
(cond
|
||||
(string/starts-with? data constants/method-id-transfer)
|
||||
:transfer
|
||||
(string/starts-with? data constants/method-id-approve)
|
||||
:approve
|
||||
(string/starts-with? data constants/method-id-approve-and-call)
|
||||
:approve-and-call))
|
||||
|
||||
(defn get-transfer-token
|
||||
[db to data]
|
||||
(let [{:keys [decimals] :as token} (tokens/address->token (:wallet-legacy/all-tokens db) to)]
|
||||
(when (and token data (string? data))
|
||||
(when-let [type (get-method-type data)]
|
||||
(let [[address value _] (native-module/decode-parameters
|
||||
(str "0x" (subs data 10))
|
||||
(if (= type :approve-and-call)
|
||||
["address" "uint256" "bytes"]
|
||||
["address" "uint256"]))]
|
||||
(when (and address value)
|
||||
{:to address
|
||||
:contact (get-contact db address)
|
||||
:contract to
|
||||
:approve? (not= type :transfer)
|
||||
:value value
|
||||
:amount (money/to-fixed (money/token->unit value decimals))
|
||||
:token token
|
||||
:symbol (:symbol token)}))))))
|
||||
|
||||
(defn parse-tx-obj
|
||||
[db {:keys [from to value data cancel?] :as tx}]
|
||||
(merge {:from {:address from}
|
||||
:cancel? cancel?
|
||||
:hash (:hash tx)}
|
||||
(if (nil? to)
|
||||
{:contact {:name (i18n/label :t/new-contract)}}
|
||||
(let [eth-value (when value (money/bignumber value))
|
||||
eth-amount (when eth-value (money/to-fixed (money/wei->ether eth-value)))
|
||||
token (get-transfer-token db to data)]
|
||||
(cond
|
||||
(and eth-amount (or (not (.equals ^js (money/bignumber 0) ^js eth-amount)) (nil? data)))
|
||||
{:to to
|
||||
:contact (get-contact db to)
|
||||
:symbol :ETH
|
||||
:value value
|
||||
:amount (str eth-amount)
|
||||
:token (tokens/asset-for (:wallet-legacy/all-tokens db)
|
||||
(chain/get-current-network db)
|
||||
:ETH)}
|
||||
(not (nil? token))
|
||||
token
|
||||
:else
|
||||
{:to to
|
||||
:contact {:address (address/normalized-hex to)}})))))
|
||||
|
||||
(defn prepare-tx
|
||||
[db {{:keys [data gas gasPrice maxFeePerGas maxPriorityFeePerGas] :as tx-obj} :tx-obj :as tx}]
|
||||
(merge
|
||||
tx
|
||||
(parse-tx-obj db tx-obj)
|
||||
{:data data
|
||||
:gas (when gas (money/bignumber gas))
|
||||
:gasPrice (when gasPrice (money/bignumber gasPrice))
|
||||
:maxFeePerGas (when maxFeePerGas
|
||||
(money/bignumber maxFeePerGas))
|
||||
:maxPriorityFeePerGas (when maxPriorityFeePerGas
|
||||
(money/bignumber maxPriorityFeePerGas))}))
|
||||
|
||||
(defn hex-to-utf8
|
||||
[s]
|
||||
(let [utf8 (native-module/hex-to-utf8 s)]
|
||||
(if (empty? utf8)
|
||||
nil
|
||||
utf8)))
|
||||
|
||||
(defn hex->text
|
||||
"Converts a hexstring to UTF8 text."
|
||||
[data]
|
||||
(or (hex-to-utf8 data) data))
|
||||
|
||||
(rf/defn show-sign
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:signing/keys [queue]} db
|
||||
{{:keys [gas gasPrice maxFeePerGas] :as tx-obj} :tx-obj
|
||||
{:keys [data typed? pinless?] :as message} :message
|
||||
:as tx}
|
||||
(last queue)
|
||||
keycard-multiaccount? (boolean (get-in db [:profile/profile :keycard-pairing]))
|
||||
wallet-set-up-passed? (get-in db [:profile/profile :wallet-set-up-passed?])]
|
||||
(if message
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc db
|
||||
:signing/queue (drop-last queue)
|
||||
:signing/tx tx
|
||||
:signing/sign {:type (cond pinless? :pinless
|
||||
keycard-multiaccount? :keycard
|
||||
:else :password)
|
||||
:formatted-data (if typed?
|
||||
(types/js->pretty-json
|
||||
(types/json->js data))
|
||||
(hex->text data))
|
||||
:keycard-step (when pinless? :connect)})
|
||||
:show-signing-sheet nil}
|
||||
#(when-not wallet-set-up-passed?
|
||||
{:dispatch-later [{:dispatch [:show-popover {:view :signing-phrase}] :ms 200}]})
|
||||
(when pinless?
|
||||
(keycard.card/start-nfc {:on-success #(re-frame/dispatch [:keycard.callback/start-nfc-success])
|
||||
:on-failure #(re-frame/dispatch
|
||||
[:keycard.callback/start-nfc-failure])})
|
||||
(signing.keycard/hash-message
|
||||
{:data data
|
||||
:typed? true
|
||||
:on-completed #(re-frame/dispatch [:keycard/store-hash-and-sign-typed %])})))
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc db
|
||||
:signing/queue (drop-last queue)
|
||||
:signing/tx (prepare-tx db tx))
|
||||
:show-signing-sheet nil
|
||||
:dismiss-keyboard nil}
|
||||
#(when-not wallet-set-up-passed?
|
||||
{:dispatch-later [{:dispatch [:show-popover {:view :signing-phrase}] :ms 200}]})
|
||||
|
||||
#(when-not gas
|
||||
{:db (assoc-in (:db %) [:signing/edit-fee :gas-loading?] true)
|
||||
:signing/update-estimated-gas {:obj (-> tx-obj
|
||||
(dissoc :gasPrice)
|
||||
(update :maxFeePerGas
|
||||
(fn [fee]
|
||||
(some-> fee
|
||||
money/bignumber
|
||||
(money/mul 2)
|
||||
money/to-hex))))
|
||||
:success-event :signing/update-estimated-gas-success
|
||||
:error-event :signing/update-estimated-gas-error}})
|
||||
(fn [cofx]
|
||||
{:db (assoc-in (:db cofx) [:signing/edit-fee :gas-price-loading?] true)
|
||||
:signing/update-gas-price
|
||||
{:success-callback #(re-frame/dispatch
|
||||
[:wallet-legacy.send/update-gas-price-success :signing/tx % tx-obj])
|
||||
:error-callback #(re-frame/dispatch [:signing/update-gas-price-error %])
|
||||
:network-id (get-in (chain/current-network db)
|
||||
[:config :NetworkId])}})))))
|
||||
|
||||
(rf/defn check-queue
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:signing/keys [tx queue]} db]
|
||||
(when (and (not tx) (seq queue))
|
||||
(show-sign cofx))))
|
||||
|
||||
(rf/defn send-transaction-message
|
||||
{:events [:sign/send-transaction-message]}
|
||||
[cofx chat-id value contract transaction-hash signature]
|
||||
{:json-rpc/call [{:method "wakuext_sendTransaction"
|
||||
;; We make sure `value` is serialized as string, and not as an integer or
|
||||
;; big-int
|
||||
:params [chat-id (str value) contract transaction-hash
|
||||
(or (:result (types/json->clj signature))
|
||||
(address/normalized-hex signature))]
|
||||
:js-response true
|
||||
:on-success
|
||||
#(re-frame/dispatch [:transport/message-sent %])}]})
|
||||
|
||||
(rf/defn send-accept-request-transaction-message
|
||||
{:events [:sign/send-accept-transaction-message]}
|
||||
[cofx message-id transaction-hash signature]
|
||||
{:json-rpc/call [{:method "wakuext_acceptRequestTransaction"
|
||||
:params [transaction-hash message-id
|
||||
(or (:result (types/json->clj signature))
|
||||
(address/normalized-hex signature))]
|
||||
:js-response true
|
||||
:on-success
|
||||
#(re-frame/dispatch [:transport/message-sent %])}]})
|
||||
|
||||
(rf/defn transaction-result
|
||||
[{:keys [db] :as cofx} result tx-obj]
|
||||
(let [{:keys [on-result symbol amount from]} (get db :signing/tx)]
|
||||
(rf/merge cofx
|
||||
{:db (dissoc db :signing/tx :signing/sign)
|
||||
:signing/show-transaction-result nil}
|
||||
(prepare-unconfirmed-transaction result tx-obj symbol amount)
|
||||
(check-queue)
|
||||
#(when on-result
|
||||
{:dispatch (conj on-result result)}))))
|
||||
|
||||
(rf/defn command-transaction-result
|
||||
[{:keys [db] :as cofx} transaction-hash hashed-password
|
||||
{:keys [message-id chat-id from] :as tx-obj}]
|
||||
(let [{:keys [on-result symbol amount contract value]} (get db :signing/tx)
|
||||
data (str (get-in db [:profile/profile :public-key])
|
||||
(subs transaction-hash 2))]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (dissoc db :signing/tx :signing/sign)}
|
||||
(if (keycard.common/keycard-multiaccount? db)
|
||||
(signing.keycard/hash-message
|
||||
{:data data
|
||||
:on-completed
|
||||
(fn [hash]
|
||||
(re-frame/dispatch
|
||||
[:keycard/sign-message
|
||||
{:tx-hash transaction-hash
|
||||
:message-id message-id
|
||||
:chat-id chat-id
|
||||
:value value
|
||||
:contract contract
|
||||
:data data}
|
||||
hash]))})
|
||||
(fn [_]
|
||||
{:signing.fx/sign-message
|
||||
{:params {:data data
|
||||
:password hashed-password
|
||||
:account from}
|
||||
:on-completed
|
||||
(fn [res]
|
||||
(re-frame/dispatch
|
||||
(if message-id
|
||||
[:sign/send-accept-transaction-message message-id transaction-hash res]
|
||||
[:sign/send-transaction-message
|
||||
chat-id value contract transaction-hash res])))}
|
||||
:signing/show-transaction-result nil}))
|
||||
(prepare-unconfirmed-transaction transaction-hash tx-obj symbol amount)
|
||||
(check-queue)
|
||||
#(when on-result
|
||||
{:dispatch (conj on-result transaction-hash)}))))
|
||||
|
||||
(rf/defn transaction-error
|
||||
[{:keys [db]} {:keys [code message]}]
|
||||
(let [on-error (get-in db [:signing/tx :on-error])]
|
||||
(if (= code constants/send-transaction-err-decrypt)
|
||||
;;wrong password
|
||||
{:db (assoc-in db [:signing/sign :error] (i18n/label :t/wrong-password))}
|
||||
(merge {:db (dissoc db :signing/tx :signing/sign)
|
||||
:signing/show-transaction-error message}
|
||||
(when on-error
|
||||
{:dispatch (conj on-error message)})))))
|
||||
|
||||
(rf/defn dissoc-signing-db-entries-and-check-queue
|
||||
{:events [:signing/dissoc-entries-and-check-queue]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (dissoc db :signing/tx :signing/sign)}
|
||||
check-queue))
|
||||
|
||||
(rf/defn sign-message-completed
|
||||
{:events [:signing/sign-message-completed]}
|
||||
[{:keys [db] :as cofx} result]
|
||||
(let [{:keys [result error]} (types/json->clj result)
|
||||
on-result (get-in db [:signing/tx :on-result])]
|
||||
(if error
|
||||
{:db (update db
|
||||
:signing/sign
|
||||
assoc
|
||||
:error (if (= 5 (:code error))
|
||||
(i18n/label :t/wrong-password)
|
||||
(:message error))
|
||||
:in-progress? false)}
|
||||
(rf/merge cofx
|
||||
(when-not (= (-> db :signing/sign :type) :pinless)
|
||||
(dissoc-signing-db-entries-and-check-queue))
|
||||
#(when (= (-> db :signing/sign :type) :pinless)
|
||||
{:dispatch-later [{:ms 3000
|
||||
:dispatch [:signing/dissoc-entries-and-check-queue]}]})
|
||||
#(when on-result
|
||||
{:dispatch (conj on-result result)})))))
|
||||
|
||||
(rf/defn transaction-completed
|
||||
{:events [:signing/transaction-completed]
|
||||
:interceptors [(re-frame/inject-cofx :random-id-generator)]}
|
||||
[cofx response tx-obj hashed-password]
|
||||
(log/info "transaction-completed" "tx-obj" tx-obj "response" response)
|
||||
(let [cofx-in-progress-false (assoc-in cofx [:db :signing/sign :in-progress?] false)
|
||||
{:keys [result error]} (types/json->clj response)]
|
||||
(if error
|
||||
(transaction-error cofx-in-progress-false error)
|
||||
(if (:command? tx-obj)
|
||||
(command-transaction-result cofx-in-progress-false result hashed-password tx-obj)
|
||||
(transaction-result cofx-in-progress-false result tx-obj)))))
|
||||
|
||||
(rf/defn discard
|
||||
"Discrad transaction signing"
|
||||
{:events [:signing.ui/cancel-is-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [on-error]} (get-in db [:signing/tx])]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :status] nil)
|
||||
(dissoc :signing/tx :signing/sign))
|
||||
:hide-signing-sheet nil}
|
||||
(check-queue)
|
||||
(keycard.common/hide-connection-sheet)
|
||||
(keycard.common/clear-pin)
|
||||
#(when on-error
|
||||
{:dispatch (conj on-error "transaction was cancelled by user")}))))
|
||||
|
||||
(defn normalize-tx-obj
|
||||
[_db tx]
|
||||
(update-in tx [:tx-obj :from] #(eip55/address->checksum %)))
|
||||
|
||||
(rf/defn sign
|
||||
"Signing transaction or message, shows signing sheet
|
||||
tx
|
||||
{:tx-obj - transaction object to send https://github.com/ethereum/wiki/wiki/JavaScript-API#parameters-25
|
||||
:message {:address :data :typed? } - message data to sign
|
||||
:on-result - re-frame event vector
|
||||
:on-error - re-frame event vector}"
|
||||
{:events [:signing.ui/sign]}
|
||||
[{:keys [db] :as cofx} tx]
|
||||
(rf/merge cofx
|
||||
{:db (update db :signing/queue conj (normalize-tx-obj db tx))}
|
||||
(check-queue)))
|
||||
|
||||
(rf/defn sign-transaction-button-clicked-from-chat
|
||||
{:events [:wallet-legacy.ui/sign-transaction-button-clicked-from-chat]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token]}]
|
||||
(let [{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (native-module/number-to-hex amount))
|
||||
to-norm (address/normalized-hex (if (string? to) to (:address to)))
|
||||
from-address (:address from)
|
||||
identity (:current-chat-id db)
|
||||
db (dissoc db :wallet-legacy/prepare-transaction :signing/edit-fee)]
|
||||
(if to-norm
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db db}
|
||||
(sign {:tx-obj (if (= symbol :ETH)
|
||||
{:to to-norm
|
||||
:from from-address
|
||||
:chat-id identity
|
||||
:command? true
|
||||
:value amount-hex}
|
||||
{:to (address/normalized-hex address)
|
||||
:from from-address
|
||||
:chat-id identity
|
||||
:command? true
|
||||
:data (native-module/encode-transfer to-norm amount-hex)})}))
|
||||
{:db db
|
||||
:json-rpc/call
|
||||
[{:method "wakuext_requestAddressForTransaction"
|
||||
:params [(:current-chat-id db)
|
||||
from-address
|
||||
amount
|
||||
(when-not (= symbol :ETH)
|
||||
address)]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent %])}]})))
|
||||
|
||||
(rf/defn sign-transaction-button-clicked-from-request
|
||||
{:events [:wallet-legacy.ui/sign-transaction-button-clicked-from-request]}
|
||||
[{:keys [db] :as cofx} {:keys [amount from token]}]
|
||||
(let [{:keys [request-parameters chat-id]} (:wallet-legacy/prepare-transaction db)
|
||||
{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (native-module/number-to-hex amount))
|
||||
to-norm (:address request-parameters)
|
||||
from-address (:address from)]
|
||||
(rf/merge cofx
|
||||
{:db (dissoc db :wallet-legacy/prepare-transaction :signing/edit-fee)}
|
||||
(fn [cofx]
|
||||
(sign
|
||||
cofx
|
||||
{:tx-obj (if (= symbol :ETH)
|
||||
{:to to-norm
|
||||
:from from-address
|
||||
:message-id (:id request-parameters)
|
||||
:chat-id chat-id
|
||||
:command? true
|
||||
:value amount-hex}
|
||||
{:to (address/normalized-hex address)
|
||||
:from from-address
|
||||
:command? true
|
||||
:message-id (:id request-parameters)
|
||||
:chat-id chat-id
|
||||
:data (native-module/encode-transfer to-norm amount-hex)})})))))
|
||||
|
||||
(rf/defn sign-transaction-button-clicked
|
||||
{:events [:wallet-legacy.ui/sign-transaction-button-clicked]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice maxFeePerGas maxPriorityFeePerGas]}]
|
||||
(let [{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (native-module/number-to-hex amount))
|
||||
to-norm (address/normalized-hex (if (string? to) to (:address to)))
|
||||
from-address (:address from)]
|
||||
(rf/merge cofx
|
||||
{:db (dissoc db :wallet-legacy/prepare-transaction :signing/edit-fee)}
|
||||
(sign
|
||||
{:tx-obj (merge (if (eip1559/sync-enabled?)
|
||||
{:from from-address
|
||||
:gas gas
|
||||
;; per eip1559
|
||||
:maxFeePerGas maxFeePerGas
|
||||
:maxPriorityFeePerGas maxPriorityFeePerGas}
|
||||
{:from from-address
|
||||
;;gas and gasPrice from qr (eip681)
|
||||
:gas gas
|
||||
:gasPrice gasPrice})
|
||||
(if (= symbol :ETH)
|
||||
{:to to-norm
|
||||
:value amount-hex}
|
||||
{:to (address/normalized-hex address)
|
||||
:data (native-module/encode-transfer to-norm amount-hex)}))}))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing/get-transaction-by-hash-fx
|
||||
(fn [[tx-hash handler]]
|
||||
(json-rpc/call
|
||||
{:method "eth_getTransactionByHash"
|
||||
:params [tx-hash]
|
||||
:on-success handler})))
|
||||
|
||||
(rf/defn cancel-transaction-pressed
|
||||
{:events [:signing.ui/cancel-transaction-pressed]}
|
||||
[_ hash]
|
||||
{:signing/get-transaction-by-hash-fx [hash #(re-frame/dispatch [:signing/cancel-transaction %])]})
|
||||
|
||||
(rf/defn increase-gas-pressed
|
||||
{:events [:signing.ui/increase-gas-pressed]}
|
||||
[_ hash]
|
||||
{:signing/get-transaction-by-hash-fx [hash #(re-frame/dispatch [:signing/increase-gas %])]})
|
||||
|
||||
(rf/defn cancel-transaction
|
||||
{:events [:signing/cancel-transaction]}
|
||||
[cofx {:keys [from nonce hash]}]
|
||||
(when (and from nonce hash)
|
||||
(sign cofx
|
||||
{:tx-obj {:from from
|
||||
:to from
|
||||
:nonce nonce
|
||||
:value "0x0"
|
||||
:cancel? true
|
||||
:hash hash}})))
|
||||
|
||||
(rf/defn increase-gas
|
||||
{:events [:signing/increase-gas]}
|
||||
[cofx {:keys [from nonce] :as tx}]
|
||||
(when (and from nonce)
|
||||
(sign cofx
|
||||
{:tx-obj (-> tx
|
||||
(select-keys [:from :to :value :input :gas :nonce :hash])
|
||||
(set/rename-keys {:input :data}))})))
|
|
@ -1,64 +0,0 @@
|
|||
(ns legacy.status-im.signing.core-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
[legacy.status-im.signing.core :as signing]
|
||||
[native-module.core :as native-module]))
|
||||
|
||||
(deftest signing-test
|
||||
(testing "showing sheet"
|
||||
(let [to "0x2f88d65f3cb52605a54a833ae118fb1363acccd2"
|
||||
contract "0xc55cf4b03948d7ebc8b9e8bad92643703811d162"
|
||||
amount1-hex (str "0x" (native-module/number-to-hex "10000000000000000000"))
|
||||
amount2-hex (str "0x" (native-module/number-to-hex "100000000000000000000"))
|
||||
data (native-module/encode-transfer to amount2-hex)
|
||||
first-tx {:tx-obj {:to to
|
||||
:from nil
|
||||
:value amount1-hex}}
|
||||
second-tx {:tx-obj {:to contract
|
||||
:from nil
|
||||
:data data}}
|
||||
sign-first (signing/sign {:db {}} first-tx)
|
||||
sign-second (signing/sign sign-first second-tx)]
|
||||
(testing "after fist transaction"
|
||||
(testing "signing in progress"
|
||||
(is (get-in sign-first [:db :signing/tx])))
|
||||
(testing "qieue is empty"
|
||||
(is (= (get-in sign-first [:db :signing/queue]) '())))
|
||||
(testing "first tx object is parsed"
|
||||
(is (= (dissoc (get-in sign-first [:db :signing/tx]) :token :hash :cancel?)
|
||||
(merge first-tx
|
||||
{:from {:address nil}
|
||||
:gas nil
|
||||
:gasPrice nil
|
||||
:maxFeePerGas nil
|
||||
:maxPriorityFeePerGas nil
|
||||
:data nil
|
||||
:to to
|
||||
:contact {:address to}
|
||||
:symbol :ETH
|
||||
:value "0x8ac7230489e80000"
|
||||
:amount "10"})))))
|
||||
(testing "after second transaction"
|
||||
(testing "signing still in progress"
|
||||
(is (get-in sign-second [:db :signing/tx])))
|
||||
(testing "queue is not empty, second tx in queue"
|
||||
(is (= (get-in sign-second [:db :signing/queue]) (list second-tx))))
|
||||
(testing "check queue does nothing"
|
||||
(is (not (signing/check-queue sign-second))))
|
||||
(let [first-discarded (signing/check-queue (update sign-second :db dissoc :signing/tx))]
|
||||
(testing "after first transaction discarded"
|
||||
(testing "signing still in progress"
|
||||
(is (get-in first-discarded [:db :signing/tx])))
|
||||
(testing "qieue is empty"
|
||||
(is (= (get-in first-discarded [:db :signing/queue]) '())))
|
||||
(testing "second tx object is parsed"
|
||||
(is (= (dissoc (get-in first-discarded [:db :signing/tx]) :token :hash :cancel?)
|
||||
(merge second-tx
|
||||
{:from {:address nil}
|
||||
:gas nil
|
||||
:gasPrice nil
|
||||
:maxFeePerGas nil
|
||||
:maxPriorityFeePerGas nil
|
||||
:data data
|
||||
:to contract
|
||||
:contact {:address contract}}))))))))))
|
|
@ -1,55 +0,0 @@
|
|||
(ns legacy.status-im.signing.eip1559
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]))
|
||||
|
||||
(defonce london-activated? (atom false))
|
||||
|
||||
(defn london-is-definitely-activated
|
||||
[network-id]
|
||||
(contains? #{"1" "3"} network-id))
|
||||
|
||||
(defn on-block
|
||||
[callback header]
|
||||
(let [activated? (contains? header :baseFeePerGas)]
|
||||
(reset! london-activated? activated?)
|
||||
(callback activated?)))
|
||||
|
||||
(defn check-activation
|
||||
[callback]
|
||||
(json-rpc/call
|
||||
{:method "eth_getBlockByNumber"
|
||||
:params ["latest" false]
|
||||
:on-success (partial on-block callback)
|
||||
:on-error #(callback nil)}))
|
||||
|
||||
(defn sync-enabled? [] @london-activated?)
|
||||
|
||||
(defn enabled?
|
||||
([] @london-activated?)
|
||||
([network-id enabled-callback disabled-callback]
|
||||
(let [definitely-activated? (london-is-definitely-activated network-id)
|
||||
enabled-callback (or enabled-callback #())
|
||||
disabled-callback (or disabled-callback #())]
|
||||
(cond
|
||||
definitely-activated?
|
||||
(do
|
||||
(reset! london-activated? true)
|
||||
(enabled-callback))
|
||||
|
||||
(not definitely-activated?)
|
||||
(check-activation
|
||||
(fn [activated?]
|
||||
(if activated?
|
||||
(enabled-callback)
|
||||
(disabled-callback))))
|
||||
|
||||
:else
|
||||
(do
|
||||
(reset! london-activated? false)
|
||||
(disabled-callback))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:check-eip1559-activation
|
||||
(fn [network-id]
|
||||
(enabled? network-id nil nil)))
|
|
@ -1,430 +0,0 @@
|
|||
(ns legacy.status-im.signing.gas
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
|
||||
[legacy.status-im.popover.core :as popover]
|
||||
[legacy.status-im.signing.eip1559 :as eip1559]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def min-gas-price-wei ^js (money/bignumber 1))
|
||||
|
||||
(def min-gas-units ^js (money/bignumber 21000))
|
||||
|
||||
(defmulti get-error-label-key (fn [type _] type))
|
||||
|
||||
(defmethod get-error-label-key :gasPrice
|
||||
[_ value]
|
||||
(cond
|
||||
(not value) :t/invalid-number
|
||||
(.lt ^js (money/->wei :gwei value) min-gas-price-wei) :t/wallet-send-min-wei
|
||||
(-> (money/->wei :gwei value) .decimalPlaces pos?) :t/invalid-number))
|
||||
|
||||
(defmethod get-error-label-key :gas
|
||||
[_ ^js value]
|
||||
(cond
|
||||
(not value) :t/invalid-number
|
||||
(.lt value min-gas-units) :t/wallet-send-min-units
|
||||
(-> value .decimalPlaces pos?) :t/invalid-number))
|
||||
|
||||
(defmethod get-error-label-key :default
|
||||
[_ value]
|
||||
(when (or (not value)
|
||||
(<= value 0))
|
||||
:t/invalid-number))
|
||||
|
||||
(defn calculate-max-fee
|
||||
[^js gas ^js gasPrice]
|
||||
(if (and gas gasPrice)
|
||||
(money/to-fixed (money/wei->ether (.times gas gasPrice)))
|
||||
"0"))
|
||||
|
||||
(defn edit-max-fee
|
||||
[edit]
|
||||
(let [gasPrice (get-in edit [:gasPrice :value-number])
|
||||
gas (get-in edit [:gas :value-number])]
|
||||
(assoc edit :max-fee (calculate-max-fee gas gasPrice))))
|
||||
|
||||
(defn build-edit
|
||||
"Takes the previous edit, either :gas or :gas-price and a value as string.
|
||||
Wei for gas, and gwei for gas price.
|
||||
Validates them and sets max fee"
|
||||
[edit-value k value]
|
||||
(let [^js bn-value (money/bignumber value)
|
||||
error-label-key (get-error-label-key k bn-value)
|
||||
data (if error-label-key
|
||||
{:value value
|
||||
:max-fee 0
|
||||
:error (i18n/label error-label-key)}
|
||||
{:value value
|
||||
:value-number (if (= :gasPrice k)
|
||||
(money/->wei :gwei bn-value)
|
||||
bn-value)})]
|
||||
(-> edit-value
|
||||
(assoc k data)
|
||||
edit-max-fee)))
|
||||
|
||||
;; TODO(rasom): this number is almost arbitrary, I was able to sent txs with
|
||||
;; 0.2 gwei tip, so it should be revisited lately
|
||||
(def minimum-priority-fee-gwei
|
||||
(money/bignumber 0.3))
|
||||
|
||||
(defn get-suggested-tip
|
||||
[latest-priority-fee]
|
||||
(money/bignumber latest-priority-fee))
|
||||
|
||||
(defn get-minimum-priority-fee
|
||||
[latest-priority-fee]
|
||||
(let [latest-priority-fee-bn (money/bignumber latest-priority-fee)
|
||||
suggested-tip-gwei (money/wei->gwei (get-suggested-tip latest-priority-fee-bn))]
|
||||
(if (money/greater-than minimum-priority-fee-gwei suggested-tip-gwei)
|
||||
(money/div suggested-tip-gwei 2)
|
||||
minimum-priority-fee-gwei)))
|
||||
|
||||
(defn get-suggestions-range
|
||||
[latest-priority-fee]
|
||||
(let [current-minimum-fee (get-minimum-priority-fee latest-priority-fee)]
|
||||
[(if (money/greater-than minimum-priority-fee-gwei current-minimum-fee)
|
||||
current-minimum-fee
|
||||
minimum-priority-fee-gwei)
|
||||
(money/wei->gwei (money/bignumber latest-priority-fee))]))
|
||||
|
||||
(def average-priority-fee
|
||||
(money/wei->gwei (money/->wei :gwei 1.5)))
|
||||
|
||||
(defn validate-max-fee
|
||||
[db]
|
||||
(let [{:keys [maxFeePerGas maxPriorityFeePerGas]} (get db :signing/edit-fee)
|
||||
latest-base-fee (money/wei->gwei
|
||||
(money/bignumber
|
||||
(get db :wallet-legacy/current-base-fee)))
|
||||
fee-error (cond
|
||||
(or (:error maxFeePerGas)
|
||||
(:error maxPriorityFeePerGas))
|
||||
nil
|
||||
|
||||
(money/greater-than latest-base-fee
|
||||
(:value-number maxFeePerGas))
|
||||
{:label (i18n/label :t/below-base-fee)
|
||||
:severity :error})]
|
||||
(if fee-error
|
||||
(assoc-in db [:signing/edit-fee :maxFeePerGas :fee-error] fee-error)
|
||||
(update-in db [:signing/edit-fee :maxFeePerGas] dissoc :fee-error))))
|
||||
|
||||
(defn validate-max-priority-fee
|
||||
[db]
|
||||
(let [{:keys [maxPriorityFeePerGas]} (get db :signing/edit-fee)
|
||||
latest-priority-fee (get db :wallet-legacy/current-priority-fee)
|
||||
fee-error (cond
|
||||
(:error maxPriorityFeePerGas)
|
||||
nil
|
||||
|
||||
(money/greater-than (get-minimum-priority-fee
|
||||
(money/div
|
||||
(money/wei->gwei (money/bignumber
|
||||
latest-priority-fee))
|
||||
2))
|
||||
(:value-number maxPriorityFeePerGas))
|
||||
{:label (i18n/label :t/low-tip)
|
||||
:severity :error}
|
||||
|
||||
#_(money/greater-than average-priority-fee
|
||||
(:value-number maxPriorityFeePerGas))
|
||||
#_{:label (i18n/label :t/lower-than-average-tip)
|
||||
:severity :error})]
|
||||
(if fee-error
|
||||
(assoc-in db [:signing/edit-fee :maxPriorityFeePerGas :fee-error] fee-error)
|
||||
(update-in db [:signing/edit-fee :maxPriorityFeePerGas] dissoc :fee-error))))
|
||||
|
||||
(defn validate-eip1559-fees
|
||||
[db]
|
||||
(if (eip1559/sync-enabled?)
|
||||
(reduce
|
||||
(fn [acc f]
|
||||
(f acc))
|
||||
db
|
||||
[validate-max-fee
|
||||
validate-max-priority-fee])
|
||||
db))
|
||||
|
||||
(rf/defn edit-value
|
||||
{:events [:signing.edit-fee.ui/edit-value]}
|
||||
[{:keys [db]} key value]
|
||||
{:db (-> db
|
||||
(assoc-in [:signing/edit-fee :selected-fee-option] :custom)
|
||||
(update :signing/edit-fee build-edit key value)
|
||||
validate-eip1559-fees)})
|
||||
|
||||
(defn get-fee-options
|
||||
[tip slow normal fast]
|
||||
(let [tip-bn (money/bignumber tip)
|
||||
normal-bn (money/bignumber normal)
|
||||
slow-bn (money/bignumber slow)
|
||||
fast-bn (money/bignumber fast)]
|
||||
{:normal
|
||||
{:base-fee normal-bn
|
||||
:tip tip-bn
|
||||
:fee (money/add normal-bn tip-bn)}
|
||||
:slow
|
||||
{:base-fee slow-bn
|
||||
:tip tip-bn
|
||||
:fee (money/add slow-bn tip-bn)}
|
||||
:fast
|
||||
{:base-fee fast-bn
|
||||
:tip tip-bn
|
||||
:fee (money/add fast-bn tip-bn)}}))
|
||||
|
||||
(rf/defn set-fee-option
|
||||
{:events [:signing.edit-fee.ui/set-option]}
|
||||
[{:keys [db] :as cofx} option]
|
||||
(let [tip (get db :wallet-legacy/current-priority-fee)
|
||||
slow (get db :wallet-legacy/slow-base-fee)
|
||||
normal (get db :wallet-legacy/normal-base-fee)
|
||||
fast (get db :wallet-legacy/fast-base-fee)
|
||||
{:keys [fee tip]} (get (get-fee-options tip slow normal fast) option)]
|
||||
{:db (-> db
|
||||
(assoc-in [:signing/edit-fee :selected-fee-option] option)
|
||||
(update :signing/edit-fee
|
||||
build-edit
|
||||
:maxFeePerGas (money/wei->gwei fee))
|
||||
(update :signing/edit-fee
|
||||
build-edit
|
||||
:maxPriorityFeePerGas (money/wei->gwei tip)))}))
|
||||
|
||||
(rf/defn set-priority-fee
|
||||
{:events [:signing.edit-fee.ui/set-priority-fee]}
|
||||
[{:keys [db]} value]
|
||||
(let [{:keys [maxFeePerGas maxPriorityFeePerGas]}
|
||||
(get db :signing/edit-fee)
|
||||
latest-base-fee (get db :wallet-legacy/current-base-fee)
|
||||
max-fee-value (:value-number maxFeePerGas)
|
||||
max-priority-fee-value (:value-number maxPriorityFeePerGas)
|
||||
new-value (money/bignumber value)
|
||||
fee-without-tip (money/sub max-fee-value max-priority-fee-value)
|
||||
base-fee (money/wei->gwei (money/bignumber latest-base-fee))
|
||||
new-max-fee-value
|
||||
(money/to-fixed
|
||||
(if (money/greater-than base-fee fee-without-tip)
|
||||
(money/add new-value base-fee)
|
||||
(money/add new-value fee-without-tip)))]
|
||||
{:db (-> db
|
||||
(update :signing/edit-fee build-edit :maxPriorityFeePerGas value)
|
||||
(update :signing/edit-fee build-edit :maxFeePerGas new-max-fee-value)
|
||||
validate-eip1559-fees)}))
|
||||
|
||||
(rf/defn update-estimated-gas-success
|
||||
{:events [:signing/update-estimated-gas-success]}
|
||||
[{db :db} gas]
|
||||
(when (contains? db :signing/tx)
|
||||
{:db (-> db
|
||||
(assoc-in [:signing/tx :gas] gas)
|
||||
(assoc-in [:signing/edit-fee :gas-loading?] false))}))
|
||||
|
||||
(rf/defn update-gas-price-success
|
||||
{:events [:signing/update-gas-price-success]}
|
||||
[{db :db} price]
|
||||
(if (eip1559/sync-enabled?)
|
||||
(let [{:keys [normal-base-fee max-priority-fee]} price
|
||||
max-priority-fee-bn (money/with-precision (get-suggested-tip
|
||||
max-priority-fee)
|
||||
0)]
|
||||
{:db (-> db
|
||||
(assoc-in [:signing/tx :maxFeePerGas]
|
||||
(money/to-hex (money/add max-priority-fee-bn
|
||||
(money/bignumber normal-base-fee))))
|
||||
(assoc-in [:signing/tx :maxPriorityFeePerGas]
|
||||
(money/to-hex max-priority-fee-bn))
|
||||
(assoc-in [:signing/edit-fee :gas-price-loading?] false))})
|
||||
{:db (-> db
|
||||
(assoc-in [:signing/tx :gasPrice] price)
|
||||
(assoc-in [:signing/edit-fee :gas-price-loading?] false))}))
|
||||
|
||||
(rf/defn update-estimated-gas-error
|
||||
{:events [:signing/update-estimated-gas-error]}
|
||||
[{db :db} {:keys [message]}]
|
||||
(log/warn "signing/update-estimated-gas-error" message)
|
||||
{:db (-> db
|
||||
(assoc-in [:signing/edit-fee :gas-loading?] false)
|
||||
(assoc-in [:signing/tx :gas-error-message] message))})
|
||||
|
||||
(rf/defn update-gas-price-error
|
||||
{:events [:signing/update-gas-price-error]}
|
||||
[{db :db}]
|
||||
{:db (assoc-in db [:signing/edit-fee :gas-price-loading?] false)})
|
||||
|
||||
(rf/defn open-fee-sheet
|
||||
{:events [:signing.ui/open-fee-sheet]}
|
||||
[{{:signing/keys [tx] :as db} :db :as cofx} sheet-opts]
|
||||
(let [{:keys [gas gasPrice maxFeePerGas maxPriorityFeePerGas]} tx
|
||||
max-fee (money/to-fixed (money/wei->gwei
|
||||
maxFeePerGas))
|
||||
max-priority-fee (money/to-fixed (money/wei->gwei
|
||||
maxPriorityFeePerGas))
|
||||
edit-fee (reduce
|
||||
(partial apply build-edit)
|
||||
{:selected-fee-option
|
||||
(get-in db
|
||||
[:signing/edit-fee
|
||||
:selected-fee-option])}
|
||||
{:gas (money/to-fixed gas)
|
||||
:gasPrice (money/to-fixed
|
||||
(money/wei->gwei gasPrice))
|
||||
:maxFeePerGas max-fee
|
||||
:maxPriorityFeePerGas
|
||||
max-priority-fee})]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db :signing/edit-fee edit-fee)}
|
||||
(bottom-sheet/show-bottom-sheet-old {:view sheet-opts}))))
|
||||
|
||||
(rf/defn submit-fee
|
||||
{:events [:signing.edit-fee.ui/submit]}
|
||||
[{{:signing/keys [edit-fee] :as db} :db :as cofx} force?]
|
||||
(let [{:keys [gas gasPrice maxFeePerGas maxPriorityFeePerGas]} edit-fee
|
||||
errors?
|
||||
(keep
|
||||
(fn [[k {:keys [fee-error]}]]
|
||||
(when (= :error (:severity fee-error))
|
||||
[k fee-error]))
|
||||
edit-fee)]
|
||||
(if (and (seq errors?)
|
||||
(not force?))
|
||||
(popover/show-popover cofx {:view :fees-warning})
|
||||
(rf/merge cofx
|
||||
{:db (update db
|
||||
:signing/tx assoc
|
||||
:gas (:value-number gas)
|
||||
:gasPrice (:value-number gasPrice)
|
||||
:maxFeePerGas (money/->wei :gwei (:value-number maxFeePerGas))
|
||||
:maxPriorityFeePerGas (money/->wei :gwei
|
||||
(:value-number maxPriorityFeePerGas)))}
|
||||
(bottom-sheet/hide-bottom-sheet-old)))))
|
||||
|
||||
(rf/defn submit-nonce
|
||||
{:events [:signing.nonce/submit]}
|
||||
[{db :db :as cofx} nonce]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:signing/tx :nonce] (if (string/blank? nonce) nil nonce))}
|
||||
(bottom-sheet/hide-bottom-sheet-old)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing/update-gas-price
|
||||
(fn [{:keys [success-callback error-callback network-id] :as params}]
|
||||
(eip1559/enabled?
|
||||
network-id
|
||||
(fn []
|
||||
(json-rpc/call
|
||||
{:method "eth_feeHistory"
|
||||
;; NOTE(rasom): We don't need `reward` atm but if the last parameter is
|
||||
;; `nil` request fails on some chains (particularly on xDai).
|
||||
:params [101 "latest" [100]]
|
||||
:on-success #(re-frame/dispatch [::header-fetched
|
||||
(assoc params :fee-history %)])}))
|
||||
(fn []
|
||||
(json-rpc/call
|
||||
{:method "eth_gasPrice"
|
||||
:on-success #(success-callback (money/bignumber %))
|
||||
:on-error (or error-callback #(log/warn "eth_gasPrice error" %))})))))
|
||||
|
||||
(def london-block-gas-limit (money/bignumber 30000000))
|
||||
|
||||
(defn calc-percentiles
|
||||
[v ps]
|
||||
(let [sorted-v (sort-by
|
||||
identity
|
||||
(fn [a b]
|
||||
(utils.money/greater-than b a))
|
||||
v)]
|
||||
(reduce
|
||||
(fn [acc p]
|
||||
(assoc acc p (nth sorted-v p)))
|
||||
{}
|
||||
ps)))
|
||||
|
||||
;; It is very unlikely to be that small on mainnet, but on testnets current base
|
||||
;; fee might be very small and using this value might slow transaction
|
||||
(def minimum-base-fee (money/->wei :gwei (money/bignumber 1)))
|
||||
|
||||
(defn recommended-base-fee
|
||||
[current perc20]
|
||||
(let [fee
|
||||
(cond (money/greater-than-or-equals current perc20)
|
||||
current
|
||||
|
||||
(money/greater-than perc20 current)
|
||||
perc20)]
|
||||
(if (money/greater-than minimum-base-fee fee)
|
||||
minimum-base-fee
|
||||
fee)))
|
||||
|
||||
(defn slow-base-fee [_ perc10] perc10)
|
||||
|
||||
(defn fast-base-fee
|
||||
[current]
|
||||
(let [fee (money/mul current 2)]
|
||||
(if (money/greater-than minimum-base-fee fee)
|
||||
(money/mul minimum-base-fee 2)
|
||||
fee)))
|
||||
|
||||
(defn check-base-fee
|
||||
[{:keys [baseFeePerGas testnet?]}]
|
||||
(let [all-base-fees (mapv money/bignumber baseFeePerGas)
|
||||
next-base-fee (peek all-base-fees)
|
||||
previous-fees (subvec all-base-fees 0 101)
|
||||
current-base-fee (peek previous-fees)
|
||||
percentiles (calc-percentiles previous-fees [10 20 80])]
|
||||
{:normal-base-fee (money/to-hex
|
||||
(if testnet?
|
||||
(fast-base-fee next-base-fee)
|
||||
(recommended-base-fee
|
||||
next-base-fee
|
||||
(get percentiles 20))))
|
||||
:slow-base-fee (money/to-hex
|
||||
(slow-base-fee
|
||||
next-base-fee
|
||||
(get percentiles 10)))
|
||||
:fast-base-fee (money/to-hex (fast-base-fee next-base-fee))
|
||||
:current-base-fee (money/to-hex current-base-fee)}))
|
||||
|
||||
(defn max-priority-fee-hex
|
||||
[gas-price base-fee]
|
||||
(money/to-hex
|
||||
(money/sub (money/bignumber gas-price)
|
||||
(money/bignumber base-fee))))
|
||||
|
||||
(rf/defn header-fetched
|
||||
{:events [::header-fetched]}
|
||||
[{{:networks/keys [current-network networks]} :db}
|
||||
{:keys [error-callback success-callback fee-history] :as params}]
|
||||
{:json-rpc/call
|
||||
[;; NOTE(rasom): eth_maxPriorityFeePerGas is not supported by some networks
|
||||
;; so it is more reliable to calculate maxPriorityFeePerGas using the value
|
||||
;; returned by eth_gasPrice and current base fee.
|
||||
{:method "eth_gasPrice"
|
||||
:on-success #(success-callback
|
||||
(let [{:keys [current-base-fee] :as base-fees}
|
||||
(check-base-fee
|
||||
(assoc fee-history
|
||||
:testnet?
|
||||
(chain/testnet?
|
||||
(get-in networks [current-network :config :NetworkId]))))]
|
||||
(merge {:max-priority-fee
|
||||
(max-priority-fee-hex (money/bignumber %) current-base-fee)}
|
||||
base-fees)))
|
||||
:on-error (if error-callback
|
||||
#(error-callback %)
|
||||
#(log/error "Can't fetch header" %))}]})
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing/update-estimated-gas
|
||||
(fn [{:keys [obj success-event error-event]}]
|
||||
(json-rpc/call
|
||||
{:method "eth_estimateGas"
|
||||
:params [obj]
|
||||
:on-success #(re-frame/dispatch [success-event
|
||||
(money/bignumber (if (= (int %) 21000) % (int (* % 1.2))))])
|
||||
:on-error #(re-frame/dispatch [error-event %])})))
|
|
@ -1,39 +0,0 @@
|
|||
(ns legacy.status-im.signing.gas-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
[legacy.status-im.signing.gas :as signing.gas]))
|
||||
|
||||
(deftest build-edit-test
|
||||
(testing "an invalid edit"
|
||||
(let [actual (-> {}
|
||||
(signing.gas/build-edit :gas "invalid")
|
||||
(signing.gas/build-edit :gasPrice "0.00000000001"))]
|
||||
(testing "it marks gasPrice as invalid"
|
||||
(is (get-in actual [:gasPrice :error])))
|
||||
(testing "it does not change value"
|
||||
(is (= "0.00000000001" (get-in actual [:gasPrice :value]))))
|
||||
(testing "it marks gas as invalid"
|
||||
(is (get-in actual [:gas :error])))
|
||||
(testing "it does not change gas value"
|
||||
(is (= "invalid" (get-in actual [:gas :value]))))
|
||||
(testing "it sets max-fee to 0"
|
||||
(is (= "0" (:max-fee actual))))))
|
||||
(testing "gas price in wei should be round"
|
||||
(let [actual (-> {}
|
||||
(signing.gas/build-edit :gas "21000")
|
||||
(signing.gas/build-edit :gasPrice "0.0000000023"))]
|
||||
(is (get-in actual [:gasPrice :error]))))
|
||||
(testing "an valid edit"
|
||||
(let [actual (-> {}
|
||||
(signing.gas/build-edit :gas "21000")
|
||||
(signing.gas/build-edit :gasPrice "10"))]
|
||||
(testing "it does not mark gas-price as invalid"
|
||||
(is (not (get-in actual [:gasPrice :error]))))
|
||||
(testing "it sets the value in number for gas-price, in gwei"
|
||||
(is (= "10000000000" (str (get-in actual [:gasPrice :value-number])))))
|
||||
(testing "it does not mark gas as invalid"
|
||||
(is (not (get-in actual [:gas :error]))))
|
||||
(testing "it sets the value in number for gasi"
|
||||
(is (= "21000" (str (get-in actual [:gas :value-number])))))
|
||||
(testing "it calculates max-fee"
|
||||
(is (= "0.00021" (:max-fee actual)))))))
|
|
@ -1,120 +0,0 @@
|
|||
(ns legacy.status-im.signing.keycard
|
||||
(:require
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::hash-transaction
|
||||
(fn [{:keys [transaction on-completed]}]
|
||||
(native-module/hash-transaction (types/clj->json transaction) on-completed)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::hash-message
|
||||
(fn [{:keys [message on-completed]}]
|
||||
(native-module/hash-message message on-completed)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::hash-typed-data
|
||||
(fn [{:keys [v4 data on-completed]}]
|
||||
(if v4
|
||||
(native-module/hash-typed-data-v4 data on-completed)
|
||||
(native-module/hash-typed-data data on-completed))))
|
||||
|
||||
(defn prepare-transaction
|
||||
[{:keys [gas gasPrice data nonce tx-obj] :as params}]
|
||||
(let [{:keys [from to value chat-id message-id command? maxPriorityFeePerGas maxFeePerGas]} tx-obj
|
||||
maxPriorityFeePerGas (or maxPriorityFeePerGas (get params :maxPriorityFeePerGas))
|
||||
maxFeePerGas (or maxFeePerGas (get params :maxFeePerGas))]
|
||||
(cond-> {:from from
|
||||
:to to
|
||||
:value value
|
||||
:chat-id chat-id
|
||||
:message-id message-id
|
||||
:command? command?}
|
||||
maxPriorityFeePerGas
|
||||
(assoc :maxPriorityFeePerGas
|
||||
(str "0x"
|
||||
(native-module/number-to-hex
|
||||
(js/parseInt maxPriorityFeePerGas))))
|
||||
maxFeePerGas
|
||||
(assoc :maxFeePerGas
|
||||
(str "0x"
|
||||
(native-module/number-to-hex
|
||||
(js/parseInt maxFeePerGas))))
|
||||
gas
|
||||
(assoc :gas (str "0x" (native-module/number-to-hex gas)))
|
||||
gasPrice
|
||||
(assoc :gasPrice (str "0x" (native-module/number-to-hex gasPrice)))
|
||||
data
|
||||
(assoc :data data)
|
||||
nonce
|
||||
(assoc :nonce nonce))))
|
||||
|
||||
(rf/defn hash-message
|
||||
[_ {:keys [v4 data typed? on-completed]}]
|
||||
(if typed?
|
||||
{::hash-typed-data
|
||||
{:data data
|
||||
:v4 v4
|
||||
:on-completed
|
||||
(or on-completed
|
||||
#(re-frame/dispatch
|
||||
[:signing.keycard.callback/hash-message-completed
|
||||
data typed? %]))}}
|
||||
{::hash-message
|
||||
{:message data
|
||||
:on-completed
|
||||
(or on-completed
|
||||
#(re-frame/dispatch
|
||||
[:signing.keycard.callback/hash-message-completed
|
||||
data typed? %]))}}))
|
||||
|
||||
(rf/defn hash-message-completed
|
||||
{:events [:signing.keycard.callback/hash-message-completed]}
|
||||
[{:keys [db]} data typed? result]
|
||||
(let [{:keys [result error]} (types/json->clj result)]
|
||||
(if error
|
||||
{:dispatch [:signing.ui/cancel-is-pressed]
|
||||
:effects.utils/show-popup {:title (i18n/label :t/sign-request-failed)
|
||||
:content (:message error)}}
|
||||
{:db (update db
|
||||
:keycard assoc
|
||||
:hash result
|
||||
:typed? typed?
|
||||
:data data)})))
|
||||
|
||||
(rf/defn hash-transaction
|
||||
[{:keys [db]}]
|
||||
(let [tx (prepare-transaction (:signing/tx db))]
|
||||
(log/debug "hash-transaction" tx)
|
||||
{::hash-transaction
|
||||
{:transaction tx
|
||||
:on-completed #(re-frame/dispatch
|
||||
[:signing.keycard.callback/hash-transaction-completed tx %])}}))
|
||||
|
||||
(rf/defn hash-transaction-completed
|
||||
{:events [:signing.keycard.callback/hash-transaction-completed]}
|
||||
[{:keys [db]} original-tx result]
|
||||
(let [{:keys [transaction hash]} (:result (types/json->clj result))]
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :transaction]
|
||||
(merge original-tx transaction))
|
||||
(assoc-in [:keycard :hash] hash))}))
|
||||
|
||||
(rf/defn sign-with-keycard
|
||||
{:events [:signing.ui/sign-with-keycard-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [message maxPriorityFeePerGas maxFeePerGas]} (get db :signing/tx)]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :enter-step] :sign)
|
||||
(assoc-in [:signing/sign :type] :keycard)
|
||||
(assoc-in [:signing/sign :keycard-step] :pin))}
|
||||
#(if message
|
||||
(hash-message % message)
|
||||
(hash-transaction %)))))
|
|
@ -1,32 +0,0 @@
|
|||
(ns legacy.status-im.subs.bootnodes
|
||||
(:require
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:custom-bootnodes/enabled?
|
||||
:<- [:profile/profile]
|
||||
:<- [:networks/current-network]
|
||||
(fn [[{:keys [custom-bootnodes-enabled?]} current-network]]
|
||||
(get custom-bootnodes-enabled? current-network)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:custom-bootnodes/network-bootnodes
|
||||
:<- [:profile/profile]
|
||||
:<- [:networks/current-network]
|
||||
(fn [[multiaccount current-network]]
|
||||
(get-in multiaccount [:custom-bootnodes current-network])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:get-manage-bootnode
|
||||
:<- [:bootnodes/manage]
|
||||
(fn [manage]
|
||||
manage))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wakuv2-nodes/validation-errors
|
||||
:<- [:wakuv2-nodes/manage]
|
||||
(fn [manage]
|
||||
(set (keep
|
||||
(fn [[k {:keys [error]}]]
|
||||
(when error k))
|
||||
manage))))
|
|
@ -1,17 +0,0 @@
|
|||
(ns legacy.status-im.subs.keycard
|
||||
(:require
|
||||
[legacy.status-im.keycard.common :as common]
|
||||
[re-frame.core :as re-frame]
|
||||
[utils.datetime :as datetime]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:keycard-paired-on
|
||||
(fn [db]
|
||||
(some-> (get-in db [:profile/profile :keycard-paired-on])
|
||||
(datetime/timestamp->year-month-day-date))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:keycard-multiaccount?
|
||||
common/keycard-multiaccount?)
|
||||
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
(ns legacy.status-im.subs.root
|
||||
(:require
|
||||
legacy.status-im.subs.bootnodes
|
||||
legacy.status-im.subs.browser
|
||||
legacy.status-im.subs.ens
|
||||
legacy.status-im.subs.keycard
|
||||
legacy.status-im.subs.mailservers
|
||||
legacy.status-im.subs.stickers
|
||||
[re-frame.core :as re-frame]))
|
||||
|
@ -23,10 +21,6 @@
|
|||
(reg-root-key-sub :peers-summary :peers-summary)
|
||||
(reg-root-key-sub :web3-node-version :web3-node-version)
|
||||
|
||||
;;keycard
|
||||
(reg-root-key-sub :keycard :keycard)
|
||||
(reg-root-key-sub :keycard/banner-hidden :keycard/banner-hidden)
|
||||
|
||||
;;bottom sheet old
|
||||
(reg-root-key-sub :bottom-sheet/show? :bottom-sheet/show?)
|
||||
(reg-root-key-sub :bottom-sheet/view :bottom-sheet/view)
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
(ns legacy.status-im.ui.screens.bootnodes-settings.edit-bootnode.styles
|
||||
(:require
|
||||
[legacy.status-im.ui.components.colors :as colors]
|
||||
[legacy.status-im.utils.styles :as styles]))
|
||||
|
||||
(def edit-bootnode-view
|
||||
{:flex 1
|
||||
:margin-horizontal 16
|
||||
:margin-vertical 15})
|
||||
|
||||
(def button-container
|
||||
{:margin-top 8
|
||||
:margin-bottom 16
|
||||
:margin-horizontal 16})
|
||||
|
||||
(styles/def button
|
||||
{:height 52
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius 8
|
||||
:ios {:opacity 0.9}})
|
||||
|
||||
(def button-label
|
||||
{:color colors/white-persist
|
||||
:font-size 17})
|
||||
|
||||
(def delete-button
|
||||
(assoc button
|
||||
:background-color
|
||||
colors/red))
|
|
@ -1,76 +0,0 @@
|
|||
(ns legacy.status-im.ui.screens.bootnodes-settings.edit-bootnode.views
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.qr-scanner.core :as qr-scanner]
|
||||
[legacy.status-im.ui.components.core :as quo]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.ui.components.toolbar :as toolbar]
|
||||
[legacy.status-im.ui.components.topbar :as topbar]
|
||||
[legacy.status-im.ui.screens.bootnodes-settings.edit-bootnode.styles :as styles]
|
||||
[re-frame.core :as re-frame]
|
||||
[utils.i18n :as i18n])
|
||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
||||
|
||||
(defn delete-button
|
||||
[id]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:bootnodes.ui/delete-pressed id])}
|
||||
[react/view styles/button-container
|
||||
[react/view
|
||||
{:style styles/delete-button
|
||||
:accessibility-label :bootnode-delete-button}
|
||||
[react/text {:style styles/button-label}
|
||||
(i18n/label :t/delete)]]]])
|
||||
|
||||
(views/defview edit-bootnode
|
||||
[]
|
||||
(views/letsubs [manage-bootnode [:get-manage-bootnode]
|
||||
validation-errors [:wakuv2-nodes/validation-errors]]
|
||||
(let [url (get-in manage-bootnode [:url :value])
|
||||
id (get-in manage-bootnode [:id :value])
|
||||
name (get-in manage-bootnode [:name :value])
|
||||
is-valid? (empty? validation-errors)
|
||||
invalid-url? (contains? validation-errors :url)]
|
||||
[react/keyboard-avoiding-view
|
||||
{:style {:flex 1}
|
||||
:ignore-offset true}
|
||||
[topbar/topbar {:title (i18n/label (if id :t/bootnode-details :t/add-bootnode))}]
|
||||
[react/scroll-view {:keyboard-should-persist-taps :handled}
|
||||
[react/view styles/edit-bootnode-view
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/name)
|
||||
:placeholder (i18n/label :t/specify-name)
|
||||
:accessibility-label :bootnode-name
|
||||
:default-value name
|
||||
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :name %])
|
||||
:auto-focus true}]]
|
||||
[react/view
|
||||
{:flex 1
|
||||
:padding-vertical 8}
|
||||
[quo/text-input
|
||||
(merge
|
||||
{:label (i18n/label :t/bootnode-address)
|
||||
:placeholder (i18n/label :t/bootnode-format)
|
||||
:accessibility-label :bootnode-address
|
||||
:default-value url
|
||||
:show-cancel false
|
||||
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :url %])
|
||||
:error (when (and (not (string/blank? url)) invalid-url?)
|
||||
(i18n/label :t/invalid-format
|
||||
{:format (i18n/label :t/bootnode-format)}))
|
||||
:bottom-value 0
|
||||
:after {:icon :main-icons/qr
|
||||
:on-press #(re-frame/dispatch
|
||||
[::qr-scanner/scan-code
|
||||
{:title (i18n/label :t/add-bootnode)
|
||||
:handler :bootnodes.callback/qr-code-scanned}])}})]]
|
||||
(when id
|
||||
[delete-button id])]]
|
||||
[toolbar/toolbar
|
||||
{:right
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:after :main-icon/next
|
||||
:disabled (not is-valid?)
|
||||
:on-press #(re-frame/dispatch [:bootnodes.ui/save-pressed])}
|
||||
(i18n/label :t/save)]}]])))
|
|
@ -1,23 +0,0 @@
|
|||
(ns legacy.status-im.ui.screens.bootnodes-settings.styles
|
||||
(:require
|
||||
[legacy.status-im.utils.styles :as styles]))
|
||||
|
||||
(def wrapper
|
||||
{:flex 1})
|
||||
|
||||
(def bootnode-item-inner
|
||||
{:padding-horizontal 16})
|
||||
|
||||
(styles/def bootnode-item
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:padding-horizontal 16
|
||||
:ios {:height 64}
|
||||
:android {:height 56}})
|
||||
|
||||
(def bootnode-item-name-text
|
||||
{:font-size 17})
|
||||
|
||||
(def switch-container
|
||||
{:height 50
|
||||
:padding-left 15})
|
|
@ -1,47 +0,0 @@
|
|||
(ns legacy.status-im.ui.screens.bootnodes-settings.views
|
||||
(:require-macros [legacy.status-im.utils.views :as views])
|
||||
(:require
|
||||
[legacy.status-im.ui.components.list.views :as list]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.ui.components.topbar :as topbar]
|
||||
[legacy.status-im.ui.screens.bootnodes-settings.styles :as styles]
|
||||
[legacy.status-im.ui.screens.profile.components.views :as profile.components]
|
||||
[re-frame.core :as re-frame]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn navigate-to-add-bootnode
|
||||
[id]
|
||||
(re-frame/dispatch [:bootnodes.ui/add-bootnode-pressed id]))
|
||||
|
||||
(defn render-row
|
||||
[{:keys [name id]}]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(navigate-to-add-bootnode id)
|
||||
:accessibility-label :bootnode-item}
|
||||
[react/view styles/bootnode-item
|
||||
[react/view styles/bootnode-item-inner
|
||||
[react/text {:style styles/bootnode-item-name-text}
|
||||
name]]]])
|
||||
|
||||
(views/defview bootnodes-settings
|
||||
[]
|
||||
(views/letsubs [bootnodes-enabled [:custom-bootnodes/enabled?]
|
||||
bootnodes [:custom-bootnodes/network-bootnodes]]
|
||||
[:<>
|
||||
[topbar/topbar
|
||||
{:title (i18n/label :t/bootnodes-settings)
|
||||
:right-accessories
|
||||
[{:icon :main-icons/add
|
||||
:accessibility-label :add-bootnode
|
||||
:on-press #(navigate-to-add-bootnode nil)}]}]
|
||||
[react/view styles/switch-container
|
||||
[profile.components/settings-switch-item
|
||||
{:label-kw :t/bootnodes-enabled
|
||||
:value bootnodes-enabled
|
||||
:action-fn #(re-frame/dispatch [:bootnodes.ui/custom-bootnodes-switch-toggled %])}]]
|
||||
[react/view styles/wrapper
|
||||
[list/flat-list
|
||||
{:data (vals bootnodes)
|
||||
:default-separator? false
|
||||
:key-fn :id
|
||||
:render-fn render-row}]]]))
|
|
@ -2,10 +2,8 @@
|
|||
(:require
|
||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
[legacy.status-im.ui.components.colors :as colors]
|
||||
[legacy.status-im.ui.components.copyable-text :as copyable-text]
|
||||
[legacy.status-im.ui.components.core :as quo]
|
||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.ui.screens.browser.styles :as styles]
|
||||
[re-frame.core :as re-frame]
|
||||
|
@ -13,7 +11,7 @@
|
|||
(:require-macros [legacy.status-im.utils.views :as views]))
|
||||
|
||||
(views/defview permissions-panel
|
||||
[dapp-name message-id params]
|
||||
[_dapp-name message-id params]
|
||||
(views/letsubs [{:keys [dapp? dapp]} [:get-current-browser]]
|
||||
[react/view {}
|
||||
[react/view styles/permissions-panel-icons-container
|
||||
|
@ -37,35 +35,6 @@
|
|||
[react/view styles/dot]]
|
||||
[react/view styles/permissions-panel-wallet-icon-container
|
||||
[icons/icon :main-icons/wallet {:color colors/white}]]]
|
||||
[react/text {:style styles/permissions-panel-title-label :number-of-lines 2}
|
||||
(str "\"" dapp-name "\" Allow this site to add a network?")]
|
||||
[react/text {:style styles/permissions-panel-description-label :number-of-lines 4}
|
||||
"This will allow this network to be used within Status.Status does not verify custom networks.Learn about scams and network security risks."]
|
||||
[react/scroll-view
|
||||
[copyable-text/copyable-text-view
|
||||
{:copied-text (:name (:new-network params))}
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:accessibility-label :network-name
|
||||
:title "Network Name"
|
||||
:accessory :text
|
||||
:accessory-text (:name (:new-network params))}]]
|
||||
[copyable-text/copyable-text-view
|
||||
{:copied-text (get-in params [:new-network :config :UpstreamConfig :URL])}
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:accessibility-label :network-url
|
||||
:title "Network URL"
|
||||
:accessory :text
|
||||
:accessory-text (get-in params [:new-network :config :UpstreamConfig :URL])}]]
|
||||
[copyable-text/copyable-text-view
|
||||
{:copied-text (str (get-in params [:new-network :config :NetworkId]))}
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:accessibility-label :network-id
|
||||
:title "Chain ID"
|
||||
:accessory :text
|
||||
:accessory-text (str (get-in params [:new-network :config :NetworkId]))}]]]
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :center
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.utils.utils :as utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.url :as url]))
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[event]
|
||||
|
@ -40,13 +38,10 @@
|
|||
:on-press #(hide-sheet-and-dispatch [:browser/revoke-dapp-permissions host])}]]))
|
||||
|
||||
(defn browser-options
|
||||
[url account empty-tab name]
|
||||
[url _account empty-tab name]
|
||||
(fn []
|
||||
(let [bookmarks @(re-frame/subscribe [:bookmarks/active])
|
||||
permissions @(re-frame/subscribe [:dapps/permissions])
|
||||
fav? (get bookmarks url)
|
||||
connected? (some #{constants/dapp-permission-web3}
|
||||
(get-in permissions [(url/url-host url) :permissions]))]
|
||||
(let [bookmarks @(re-frame/subscribe [:bookmarks/active])
|
||||
fav? (get bookmarks url)]
|
||||
[react/view {:flex 1}
|
||||
[quo/button
|
||||
{:style {:align-self :flex-end
|
||||
|
@ -86,21 +81,4 @@
|
|||
#(browser/share-link url)
|
||||
200))}]
|
||||
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]])
|
||||
(if connected?
|
||||
[list.item/list-item
|
||||
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
||||
:title (:name account)
|
||||
:subtitle (i18n/label :t/connected)
|
||||
:accessibility-label :connected-account
|
||||
:chevron true
|
||||
:on-press #(hide-sheet-and-dispatch
|
||||
[:bottom-sheet/show-sheet-old
|
||||
{:content (wallet-connection (url/url-host url) account)}])}]
|
||||
[list.item/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/connect-wallet)
|
||||
:accessibility-label :connect-account
|
||||
:icon :main-icons/wallet
|
||||
:on-press #(hide-sheet-and-dispatch
|
||||
[:browser/bridge-message-received
|
||||
"{\"type\":\"api-request\",\"permission\":\"web3\"}"])}])])))
|
||||
])))
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.ui.screens.profile.user.views :as profile.user]
|
||||
[legacy.status-im.ui.screens.reset-password.views :as reset-password.views]
|
||||
[legacy.status-im.ui.screens.signing.sheets :as signing-sheets]
|
||||
[legacy.status-im.ui.screens.signing.views :as signing]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]))
|
||||
|
@ -132,15 +130,9 @@
|
|||
(= :share-chat-key view)
|
||||
[profile.user/share-chat-key]
|
||||
|
||||
(= :transaction-data view)
|
||||
[signing/transaction-data]
|
||||
|
||||
(= :password-reset-popover view)
|
||||
[reset-password.views/reset-password-popover]
|
||||
|
||||
(= :fees-warning view)
|
||||
[signing-sheets/fees-warning]
|
||||
|
||||
:else
|
||||
[view])]]]])))})))
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(ns legacy.status-im.ui.screens.privacy-and-security-settings.delete-profile
|
||||
(:require
|
||||
legacy.status-im.keycard.delete-key
|
||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
[legacy.status-im.ui.components.core :as quo]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
|
@ -23,18 +22,12 @@
|
|||
[::delete-profile/delete-profile @password])
|
||||
(reset! password nil)))
|
||||
|
||||
(defn on-delete-keycard-profile
|
||||
[keep-keys-on-keycard?]
|
||||
#(re-frame/dispatch
|
||||
[:keycard/proceed-to-reset-card keep-keys-on-keycard?]))
|
||||
|
||||
(defn delete-profile
|
||||
[]
|
||||
(let [password (reagent/atom nil)
|
||||
text-input-ref (atom nil)]
|
||||
(fn []
|
||||
(let [profile @(re-frame/subscribe [:profile/profile])
|
||||
keycard? @(re-frame/subscribe [:keycard-multiaccount?])
|
||||
error @(re-frame/subscribe [:delete-profile/error])
|
||||
keep-keys-on-keycard? @(re-frame/subscribe
|
||||
[:delete-profile/keep-keys-on-keycard?])]
|
||||
|
@ -50,55 +43,29 @@
|
|||
[list.item/list-item
|
||||
{:title (profile.utils/displayed-name profile)
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab profile]}]
|
||||
(when keycard?
|
||||
[react/view
|
||||
[quo/list-header (i18n/label :t/actions)]
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/delete-keys-keycard)
|
||||
:accessory :checkbox
|
||||
:active (not keep-keys-on-keycard?)
|
||||
:on-press #(re-frame/dispatch [::delete-profile/keep-keys-on-keycard
|
||||
(not keep-keys-on-keycard?)])}]
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/unpair-keycard)
|
||||
:subtitle (i18n/label :t/unpair-keycard-warning)
|
||||
:subtitle-max-lines 4
|
||||
:disabled true
|
||||
:active true
|
||||
:accessory :checkbox}]
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/reset-database)
|
||||
:subtitle (i18n/label :t/reset-database-warning-keycard)
|
||||
:subtitle-max-lines 4
|
||||
:disabled true
|
||||
:active true
|
||||
:accessory :checkbox}]])
|
||||
(when-not keycard?
|
||||
[quo/text
|
||||
{:style {:margin-horizontal 24}
|
||||
:align :center
|
||||
:color :negative}
|
||||
(i18n/label :t/delete-profile-warning)])
|
||||
(when-not keycard?
|
||||
[quo/text-input
|
||||
{:style {:margin-horizontal 36
|
||||
:margin-top 36}
|
||||
:show-cancel false
|
||||
:secure-text-entry true
|
||||
:return-key-type :next
|
||||
:on-submit-editing nil
|
||||
:auto-focus true
|
||||
:on-change-text #(reset! password (security/mask-data %))
|
||||
:bottom-value 36
|
||||
:get-ref #(reset! text-input-ref %)
|
||||
:error (when (and error (not @password))
|
||||
(if (= :wrong-password error)
|
||||
(i18n/label :t/wrong-password)
|
||||
(str error)))}])]
|
||||
[quo/text
|
||||
{:style {:margin-horizontal 24}
|
||||
:align :center
|
||||
:color :negative}
|
||||
(i18n/label :t/delete-profile-warning)]
|
||||
[quo/text-input
|
||||
{:style {:margin-horizontal 36
|
||||
:margin-top 36}
|
||||
:show-cancel false
|
||||
:secure-text-entry true
|
||||
:return-key-type :next
|
||||
:on-submit-editing nil
|
||||
:auto-focus true
|
||||
:on-change-text #(reset! password (security/mask-data %))
|
||||
:bottom-value 36
|
||||
:get-ref #(reset! text-input-ref %)
|
||||
:error (when (and error (not @password))
|
||||
(if (= :wrong-password error)
|
||||
(i18n/label :t/wrong-password)
|
||||
(str error)))}]]
|
||||
[react/view {:style {:align-items :center}}
|
||||
(when-not keycard?
|
||||
[quo/separator])
|
||||
(when (and keycard? (not keep-keys-on-keycard?))
|
||||
[quo/separator]
|
||||
(when (not keep-keys-on-keycard?)
|
||||
[quo/text
|
||||
{:style {:margin-horizontal 24 :margin-bottom 16}
|
||||
:align :center
|
||||
|
@ -107,10 +74,8 @@
|
|||
[react/view
|
||||
{:style {:margin-vertical 8}}
|
||||
[quo/button
|
||||
{:on-press (if keycard?
|
||||
(on-delete-keycard-profile keep-keys-on-keycard?)
|
||||
(on-delete-profile password))
|
||||
{:on-press (on-delete-profile password)
|
||||
:theme :negative
|
||||
:accessibility-label :delete-profile-confirm
|
||||
:disabled (and (not keycard?) ((complement valid-password?) @password))}
|
||||
:disabled ((complement valid-password?) @password)}
|
||||
(i18n/label :t/delete-profile)]]]]))))
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
profile-pictures-visibility]}
|
||||
[:profile/profile]
|
||||
has-picture [:profile/has-picture]
|
||||
keycard? [:keycard-multiaccount?]
|
||||
profile-pictures-show-to [:multiaccount/profile-pictures-show-to]]
|
||||
[react/scroll-view {:padding-vertical 8}
|
||||
[quo/list-header (i18n/label :t/security)]
|
||||
|
@ -92,16 +91,15 @@
|
|||
:t/anyone))
|
||||
:on-press #(re-frame/dispatch [:navigate-to :messages-from-contacts-only])
|
||||
:accessibility-label :accept-new-chats-from}]
|
||||
(when (not keycard?)
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/reset-password)
|
||||
:chevron true
|
||||
:accessory :text
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [::reset-password/clear-form-vals])
|
||||
(re-frame/dispatch [:navigate-to :reset-password]))
|
||||
:accessibility-label :reset-password}])
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/reset-password)
|
||||
:chevron true
|
||||
:accessory :text
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [::reset-password/clear-form-vals])
|
||||
(re-frame/dispatch [:navigate-to :reset-password]))
|
||||
:accessibility-label :reset-password}]
|
||||
(when platform/android?
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
|
|
|
@ -73,8 +73,7 @@
|
|||
(defn content
|
||||
[]
|
||||
(let [{:keys [preferred-name
|
||||
mnemonic
|
||||
keycard-pairing]}
|
||||
mnemonic]}
|
||||
@(re-frame/subscribe [:profile/profile])
|
||||
active-contacts-count @(re-frame/subscribe [:contacts/active-count])
|
||||
chain @(re-frame/subscribe [:chain-keyword])
|
||||
|
@ -155,13 +154,6 @@
|
|||
:accessibility-label :sync-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :sync-settings])}]
|
||||
(when keycard-pairing
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/keycard
|
||||
:title (i18n/label :t/keycard)
|
||||
:accessibility-label :keycard-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :keycard-settings])}])
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/settings-advanced
|
||||
:title (i18n/label :t/advanced)
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
[legacy.status-im.ui.screens.advanced-settings.views :as advanced-settings]
|
||||
[legacy.status-im.ui.screens.appearance.views :as appearance]
|
||||
[legacy.status-im.ui.screens.backup-settings.view :as backup-settings]
|
||||
[legacy.status-im.ui.screens.bootnodes-settings.edit-bootnode.views :as edit-bootnode]
|
||||
[legacy.status-im.ui.screens.bootnodes-settings.views :as bootnodes-settings]
|
||||
[legacy.status-im.ui.screens.browser.bookmarks.views :as bookmarks]
|
||||
[legacy.status-im.ui.screens.bug-report :as bug-report]
|
||||
[legacy.status-im.ui.screens.communities.invite :as communities.invite]
|
||||
|
@ -136,18 +134,10 @@
|
|||
;;TODO dynamic title
|
||||
:options {:insets {:top? true}}
|
||||
:component edit-wakuv2-node/edit-node}
|
||||
{:name :bootnodes-settings
|
||||
;;TODO dynamic title
|
||||
:options {:insets {:top? true}}
|
||||
:component bootnodes-settings/bootnodes-settings}
|
||||
{:name :installations
|
||||
:options {:topBar (topbar-options (i18n/label :t/devices))
|
||||
:insets {:top? true}}
|
||||
:component pairing/installations}
|
||||
{:name :edit-bootnode
|
||||
;;TODO dynamic title
|
||||
:options {:insets {:top? true}}
|
||||
:component edit-bootnode/edit-bootnode}
|
||||
{:name :offline-messaging-settings
|
||||
;;TODO dynamic title
|
||||
:options {:insets {:top? true}}
|
||||
|
|
|
@ -1,437 +0,0 @@
|
|||
(ns legacy.status-im.ui.screens.signing.sheets
|
||||
(:require-macros [legacy.status-im.utils.views :as views])
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.signing.gas :as gas]
|
||||
[legacy.status-im.ui.components.colors :as colors]
|
||||
[legacy.status-im.ui.components.core :as quo]
|
||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]))
|
||||
|
||||
(views/defview fee-bottom-sheet
|
||||
[fee-display-symbol]
|
||||
(views/letsubs [{gas-edit :gas gas-price-edit :gasPrice max-fee :max-fee} [:signing/edit-fee]]
|
||||
[react/view
|
||||
[react/view {:style {:margin-horizontal 16 :margin-top 8}}
|
||||
[react/text {:style {:typography :title-bold}} (i18n/label :t/network-fee)]
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:margin-top 8
|
||||
:align-items :flex-end}}
|
||||
[react/view {:flex 1}
|
||||
[quo/text-input
|
||||
{:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :gas %])
|
||||
:label (i18n/label :t/gas-limit)
|
||||
:bottom-value 0
|
||||
:error (:error gas-edit)
|
||||
:default-value (:value gas-edit)
|
||||
:keyboard-type :numeric
|
||||
:auto-capitalize :none
|
||||
:placeholder "0"
|
||||
:show-cancel false
|
||||
:auto-focus false}]]
|
||||
[react/view
|
||||
{:flex 1
|
||||
:padding-left 16}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/gas-price)
|
||||
:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :gasPrice %])
|
||||
:bottom-value 0
|
||||
:error (:error gas-price-edit)
|
||||
:default-value (:value gas-price-edit)
|
||||
:keyboard-type :numeric
|
||||
:auto-capitalize :none
|
||||
:placeholder "0.000"
|
||||
:show-cancel false
|
||||
:auto-focus false}]]
|
||||
[react/view
|
||||
{:padding-left 8
|
||||
:padding-bottom 12}
|
||||
[react/text (i18n/label :t/gwei)]]]
|
||||
|
||||
[react/view {:margin-vertical 16 :align-items :center}
|
||||
[react/text {:style {:color colors/gray}} (i18n/label :t/wallet-transaction-total-fee)]
|
||||
[react/view {:height 8}]
|
||||
[react/nested-text {:style {:font-size 17}}
|
||||
max-fee " "
|
||||
[{:style {:color colors/gray}} fee-display-symbol]]]]
|
||||
[react/view {:height 1 :background-color colors/gray-lighter}]
|
||||
[react/view
|
||||
{:margin-horizontal 16
|
||||
:align-items :center
|
||||
:justify-content :space-between
|
||||
:flex-direction :row
|
||||
:margin-top 6}
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:on-press #(re-frame/dispatch [:bottom-sheet/hide-old])}
|
||||
(i18n/label :t/cancel)]
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/submit])
|
||||
:disabled (or (:error gas-edit) (:error gas-price-edit))}
|
||||
(i18n/label :t/update)]]]))
|
||||
|
||||
(declare fee-bottom-sheet-eip1559)
|
||||
|
||||
(defn fee-bottom-sheet-eip1559-custom
|
||||
[_ #_fee-display-symbol]
|
||||
(let [{gas-edit :gas
|
||||
max-fee-per-gas-edit :maxFeePerGas
|
||||
max-priority-fee-per-gas-edit :maxPriorityFeePerGas}
|
||||
@(re-frame/subscribe [:signing/edit-fee])
|
||||
error? (some :error
|
||||
[gas-edit
|
||||
max-fee-per-gas-edit
|
||||
max-priority-fee-per-gas-edit])
|
||||
base-fee @(re-frame/subscribe [:wallet-legacy/current-base-fee])
|
||||
[fee-currency fiat-currency price]
|
||||
@(re-frame/subscribe [:signing/currencies])
|
||||
fee-eth
|
||||
(if (and (:value-number gas-edit)
|
||||
(:value-number max-fee-per-gas-edit))
|
||||
(money/mul
|
||||
(money/wei->ether
|
||||
(money/->wei :gwei (:value-number max-fee-per-gas-edit)))
|
||||
(:value-number gas-edit))
|
||||
(money/bignumber 0))]
|
||||
[:<>
|
||||
[react/view {:style {:margin-horizontal 16 :margin-top 8}}
|
||||
[react/text {:style {:typography :title-bold}} (i18n/label :t/max-priority-fee)]
|
||||
[react/text
|
||||
{:style {:color (colors/get-color :text-02)
|
||||
:margin-top 12}}
|
||||
(i18n/label :t/miners-higher-fee)]
|
||||
[react/view
|
||||
{:style {:margin-top 12
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between}}
|
||||
[quo/text (i18n/label :t/current-base-fee)]
|
||||
[quo/text
|
||||
(money/to-fixed (money/wei-> :gwei base-fee))
|
||||
" "
|
||||
(i18n/label :t/gwei)]]]
|
||||
[react/view
|
||||
{:margin-vertical 12
|
||||
:margin-horizontal 16
|
||||
:height 1
|
||||
:background-color colors/gray-lighter}]
|
||||
[react/view
|
||||
{:margin-horizontal 16
|
||||
:margin-top 4
|
||||
:margin-bottom 26}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/gas-amount-limit)
|
||||
:accessibility-label :gas-amount-limit
|
||||
:error (:error gas-edit)
|
||||
:default-value (:value gas-edit)
|
||||
:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :gas %])
|
||||
:show-cancel false}]]
|
||||
[react/view
|
||||
{:margin-horizontal 16
|
||||
:margin-top 4
|
||||
:margin-bottom 26}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/per-gas-tip-limit)
|
||||
:accessibility-label :per-gas-tip-limit
|
||||
:error (or (:error max-priority-fee-per-gas-edit)
|
||||
(get-in max-priority-fee-per-gas-edit [:fee-error :label]))
|
||||
:default-value (str (:value max-priority-fee-per-gas-edit))
|
||||
:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :maxPriorityFeePerGas
|
||||
%])
|
||||
:show-cancel false
|
||||
:after {:component [quo/text
|
||||
{:style {:color (colors/get-color :text-02)}}
|
||||
(i18n/label :t/gwei)]}}]]
|
||||
[react/view
|
||||
{:margin-horizontal 16
|
||||
:margin-top 4
|
||||
:margin-bottom 12}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/per-gas-price-limit)
|
||||
:accessibility-label :per-gas-price-limit
|
||||
:error (or (:error max-fee-per-gas-edit)
|
||||
(get-in max-fee-per-gas-edit [:fee-error :label]))
|
||||
:default-value (str (:value max-fee-per-gas-edit))
|
||||
:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :maxFeePerGas %])
|
||||
:show-cancel false
|
||||
:after {:component [quo/text
|
||||
{:style {:color (colors/get-color :text-02)}}
|
||||
(i18n/label :t/gwei)]}}]]
|
||||
[react/view
|
||||
{:margin-vertical 12
|
||||
:height 1
|
||||
:background-color colors/gray-lighter}]
|
||||
[react/view
|
||||
{:style {:margin-top 4
|
||||
:margin-horizontal 16
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between}}
|
||||
[quo/text (i18n/label :t/maximum-fee) ":"]
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :flex-end}}
|
||||
[quo/text
|
||||
{:style {:margin-right 6
|
||||
:color (colors/get-color :text-02)}}
|
||||
(str (money/to-fixed fee-eth 6) " " fee-currency)]
|
||||
[quo/text
|
||||
(money/to-fixed (money/mul fee-eth (money/bignumber (or price 0))) 2)
|
||||
" "
|
||||
fiat-currency]]]
|
||||
[react/text
|
||||
{:style {:color (colors/get-color :text-02)
|
||||
:margin 16}}
|
||||
(i18n/label :t/fee-explanation)]
|
||||
[react/view
|
||||
{:style {:margin-left 12
|
||||
:margin-right 16
|
||||
:margin-bottom 20
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between}}
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:accessibility-label :see-fee-suggestions
|
||||
;;:on-press
|
||||
#_(re-frame/dispatch
|
||||
[:bottom-sheet/show-sheet-old
|
||||
{:content (fn []
|
||||
[fee-bottom-sheet-eip1559 fee-display-symbol])
|
||||
:content-height 270}])}
|
||||
"" #_(i18n/label :t/see-suggestions)]
|
||||
[quo/button
|
||||
{:type :primary
|
||||
:accessibility-label :save-fees
|
||||
:disabled error?
|
||||
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/submit])
|
||||
:theme :accent}
|
||||
(i18n/label :t/save)]]]))
|
||||
|
||||
(defn fee-bottom-sheet-eip1559
|
||||
[fee-display-symbol]
|
||||
(let [{priority-fee-edit :maxPriorityFeePerGas
|
||||
option :selected-fee-option
|
||||
fee-edit :maxFeePerGas}
|
||||
@(re-frame/subscribe [:signing/edit-fee])
|
||||
{:keys [normal fast slow]}
|
||||
@(re-frame/subscribe [:signing/priority-fee-suggestions-range])]
|
||||
[react/view
|
||||
[react/view {:style {:margin-horizontal 16 :margin-top 8}}
|
||||
[react/text {:style {:typography :title-bold}} (i18n/label :t/fee-options)]
|
||||
[react/text
|
||||
{:style {:margin-top 12}
|
||||
:accessibility-label :slow-fee
|
||||
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/set-option :slow])}
|
||||
(string/join
|
||||
" "
|
||||
[(str (i18n/label :t/slow) ":")
|
||||
(str (:base-fee slow) " gwei")
|
||||
(str (:tip slow) " gwei")
|
||||
(when (= :slow option)
|
||||
"<- selected")])]
|
||||
[react/text
|
||||
{:style {:margin-top 12}
|
||||
:accessibility-label :normal-fee
|
||||
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/set-option :normal])}
|
||||
(string/join
|
||||
" "
|
||||
[(str (i18n/label :t/normal) ":")
|
||||
(str (:base-fee normal) " gwei")
|
||||
(str (:tip normal) " gwei")
|
||||
(when (or (nil? option)
|
||||
(= :normal option))
|
||||
"<- selected")])]
|
||||
[react/text
|
||||
{:style {:margin-top 12}
|
||||
:accessibility-label :fast-fee
|
||||
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/set-option :fast])}
|
||||
(string/join
|
||||
" "
|
||||
[(str (i18n/label :t/fast) ":")
|
||||
(str (:base-fee fast) " gwei")
|
||||
(str (:tip fast) " gwei")
|
||||
(when (= :fast option)
|
||||
"<- selected")])]
|
||||
(when (= :custom option)
|
||||
[react/text {:style {:margin-top 12}}
|
||||
(string/join
|
||||
" "
|
||||
[(str (i18n/label :t/custom) ":")
|
||||
(str (-> fee-edit
|
||||
:value-number
|
||||
(money/to-fixed 2))
|
||||
" gwei")
|
||||
(str (-> priority-fee-edit
|
||||
:value-number
|
||||
(money/to-fixed 2))
|
||||
" gwei")
|
||||
(when (= :custom option)
|
||||
"<- selected")])])]
|
||||
[react/view
|
||||
{:style {:margin-left 12
|
||||
:margin-right 16
|
||||
:margin-top 38}
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between}
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:accessibility-label :set-custom-fee
|
||||
:on-press #(re-frame/dispatch
|
||||
[:bottom-sheet/show-sheet-old
|
||||
{:content (fn []
|
||||
[fee-bottom-sheet-eip1559-custom fee-display-symbol])
|
||||
:content-height 270}])}
|
||||
(i18n/label :t/set-custom-fee)]
|
||||
[quo/button
|
||||
{:type :primary
|
||||
:accessibility-label :save-custom-fee
|
||||
:theme :accent
|
||||
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/submit])}
|
||||
(i18n/label :t/save)]]]))
|
||||
|
||||
(defn gwei
|
||||
[amount]
|
||||
(str (money/to-fixed amount 2)
|
||||
" "
|
||||
(i18n/label :t/gwei)))
|
||||
|
||||
(defn fees-warning
|
||||
[]
|
||||
(let [base-fee @(re-frame/subscribe [:wallet-legacy/current-base-fee])
|
||||
base-fee-gwei (money/wei-> :gwei (money/bignumber base-fee))
|
||||
priority-fee @(re-frame/subscribe [:wallet-legacy/current-priority-fee])
|
||||
priority-fee-gwei (money/wei-> :gwei (money/bignumber priority-fee))
|
||||
{priority-fee-edit :maxPriorityFeePerGas
|
||||
fee-edit :maxFeePerGas}
|
||||
@(re-frame/subscribe [:signing/edit-fee])]
|
||||
[react/view
|
||||
[react/view
|
||||
{:margin-top 24
|
||||
:margin-horizontal 24
|
||||
:margin-bottom 32
|
||||
:align-items :center}
|
||||
[react/view
|
||||
{:background-color colors/blue-light
|
||||
:width 32
|
||||
:height 32
|
||||
:border-radius 16
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
[icons/icon :main-icons/warning {:color colors/black}]]
|
||||
[react/text
|
||||
{:style {:typography :title-bold
|
||||
:margin-top 16
|
||||
:margin-bottom 8}}
|
||||
(i18n/label :t/are-you-sure)]
|
||||
[react/text
|
||||
{:style {:color colors/gray
|
||||
:text-align :center
|
||||
:margin-horizontal 24}}
|
||||
(i18n/label :t/bad-fees-description)]]
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:margin-horizontal 32}}
|
||||
[react/text (i18n/label :t/current-base-fee)]
|
||||
[react/text (gwei base-fee-gwei)]]
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:margin-horizontal 32}}
|
||||
[react/text (i18n/label :t/current-minimum-tip)]
|
||||
[react/text (gwei (gas/get-minimum-priority-fee priority-fee))]]
|
||||
;;TODO(rasom): we can uncomment it once it will be clear which value can be
|
||||
;;used as "average" here
|
||||
#_[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:margin-horizontal 32}}
|
||||
[react/text (i18n/label :t/current-average-tip)]
|
||||
[react/text (gwei (money/to-fixed priority-fee-gwei 2))]]
|
||||
[react/view
|
||||
{:margin-vertical 16
|
||||
:height 1
|
||||
:background-color colors/gray-lighter}]
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:margin-horizontal 32
|
||||
:color :red}}
|
||||
[react/text {:style {:color (colors/get-color :negative-01)}}
|
||||
(i18n/label :t/your-tip-limit)]
|
||||
[react/text {:style {:color (colors/get-color :negative-01)}}
|
||||
(gwei (:value-number priority-fee-edit))]]
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:margin-horizontal 32}}
|
||||
[react/text {:style {:color (colors/get-color :negative-01)}}
|
||||
(i18n/label :t/your-price-limit)]
|
||||
[react/text {:style {:color (colors/get-color :negative-01)}}
|
||||
(gwei (:value-number fee-edit))]]
|
||||
[react/view
|
||||
{:style
|
||||
{:background-color colors/gray-lighter
|
||||
:padding-horizontal 32
|
||||
:padding-vertical 16
|
||||
:margin-vertical 16}}
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between}}
|
||||
[react/text (i18n/label :t/suggested-min-tip)]
|
||||
[react/text (gwei priority-fee-gwei)]]
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between}}
|
||||
[react/text (i18n/label :t/suggested-price-limit)]
|
||||
[react/text (gwei (money/add base-fee-gwei priority-fee-gwei))]]]
|
||||
[react/view
|
||||
{:style {:align-items :center
|
||||
:justify-content :center
|
||||
:margin-top 8}}
|
||||
[quo/button
|
||||
{:type :primary
|
||||
:on-press #(re-frame/dispatch [:hide-popover])}
|
||||
(i18n/label :t/change-tip)]]
|
||||
[react/view
|
||||
{:style {:align-items :center
|
||||
:justify-content :center
|
||||
:margin-top 8
|
||||
:margin-bottom 16}}
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:on-press #(do (re-frame/dispatch [:hide-popover])
|
||||
(re-frame/dispatch [:signing.edit-fee.ui/submit true]))}
|
||||
(i18n/label :t/continue-anyway)]]]))
|
||||
|
||||
(defn advanced
|
||||
[]
|
||||
(let [nonce (reagent/atom nil)
|
||||
default-nonce (:nonce @(re-frame/subscribe [:signing/tx]))]
|
||||
(fn []
|
||||
[react/view {:padding 20}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/nonce)
|
||||
:accessibility-label :nonce
|
||||
:keyboard-type :numeric
|
||||
:default-value default-nonce
|
||||
:on-change-text #(reset! nonce %)
|
||||
:show-cancel false
|
||||
:auto-focus true
|
||||
:container-style {:margin-bottom 20}}]
|
||||
[react/view {:align-items :flex-end}
|
||||
[quo/button
|
||||
{:type :primary
|
||||
:accessibility-label :save-nonce
|
||||
:theme :accent
|
||||
:on-press #(re-frame/dispatch [:signing.nonce/submit @nonce])}
|
||||
(i18n/label :t/save)]]])))
|
|
@ -1,65 +0,0 @@
|
|||
(ns legacy.status-im.ui.screens.signing.styles
|
||||
(:require
|
||||
[legacy.status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def header
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between
|
||||
:padding-top 16
|
||||
:padding-left 16
|
||||
:margin-bottom 11})
|
||||
|
||||
(def message-header
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between
|
||||
:padding-top 20
|
||||
:padding-left 16
|
||||
:padding-right 24
|
||||
:margin-bottom 19})
|
||||
|
||||
(defn message
|
||||
[]
|
||||
{:background-color colors/white
|
||||
:border-top-right-radius 16
|
||||
:border-top-left-radius 16
|
||||
:padding-bottom 40})
|
||||
|
||||
(def message-border
|
||||
{:margin-horizontal 24
|
||||
:max-height 96
|
||||
:min-height 35
|
||||
:flex 1
|
||||
:border-radius 8
|
||||
:border-color colors/black-transparent
|
||||
:border-width 1
|
||||
:padding 8})
|
||||
|
||||
(defn sheet
|
||||
[]
|
||||
{:background-color colors/white
|
||||
:border-top-right-radius 16
|
||||
:border-top-left-radius 16
|
||||
:padding-bottom 40})
|
||||
|
||||
(defn sign-with-keycard-button
|
||||
[disabled?]
|
||||
{:background-color (if (colors/dark?) "#27D8B9" colors/black-light)
|
||||
:padding-top 2
|
||||
:border-radius 8
|
||||
:width 182
|
||||
:height 44
|
||||
:flex-direction :row
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:opacity (if disabled? 0.1 1)
|
||||
:padding-horizontal 12})
|
||||
|
||||
(defn sign-with-keycard-button-text
|
||||
[disabled?]
|
||||
{:padding-right 2
|
||||
:padding-left 16
|
||||
:color (if disabled? colors/black colors/white-persist)
|
||||
:padding-horizontal 16
|
||||
:padding-vertical 10})
|
|
@ -1,386 +0,0 @@
|
|||
(ns legacy.status-im.ui.screens.signing.views
|
||||
(:require-macros [legacy.status-im.utils.views :as views])
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.react-native.resources :as resources]
|
||||
[legacy.status-im.signing.eip1559 :as eip1559]
|
||||
[legacy.status-im.ui.components.bottom-panel.views :as bottom-panel]
|
||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[legacy.status-im.ui.components.colors :as colors]
|
||||
[legacy.status-im.ui.components.copyable-text :as copyable-text]
|
||||
[legacy.status-im.ui.components.core :as quo]
|
||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.ui.screens.signing.sheets :as sheets]
|
||||
[legacy.status-im.ui.screens.signing.styles :as styles]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[legacy.status-im.utils.utils :as utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(defn separator
|
||||
[]
|
||||
[react/view {:height 1 :background-color colors/gray-lighter}])
|
||||
|
||||
(defn contact-item
|
||||
[title {:keys [address] :as profile}]
|
||||
[copyable-text/copyable-text-view
|
||||
{:copied-text address}
|
||||
[list.item/list-item
|
||||
{:title title
|
||||
:title-prefix-width 45
|
||||
:size :small
|
||||
:accessory :text
|
||||
:accessory-text [quo/text
|
||||
{:ellipsize-mode :middle
|
||||
:number-of-lines 1
|
||||
:monospace true}
|
||||
(profile.utils/displayed-name profile)]}]])
|
||||
|
||||
(defn token-item
|
||||
[{:keys [icon color] :as token} display-symbol]
|
||||
(when token
|
||||
[react/view
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/wallet-asset)
|
||||
:accessory [react/view {:flex-direction :row}
|
||||
[quo/text
|
||||
{:color :secondary
|
||||
:style {:margin-right 8}}
|
||||
display-symbol]
|
||||
(if icon
|
||||
[react/view]
|
||||
[chat-icon/custom-icon-view-list (:name token) color 32])]}]
|
||||
[separator]]))
|
||||
|
||||
(defn header
|
||||
[{:keys [in-progress?] :as sign}
|
||||
{:keys [contact amount approve? cancel?] :as tx}
|
||||
display-symbol fee fee-display-symbol]
|
||||
[react/view styles/header
|
||||
(when sign
|
||||
[react/touchable-highlight
|
||||
(when-not in-progress? {:on-press #(re-frame/dispatch [:set :signing/sign nil])})
|
||||
[react/view {:padding-right 16}
|
||||
[icons/icon :main-icons/back]]])
|
||||
[react/view {:flex 1}
|
||||
(if amount
|
||||
[react/text {:style {:typography :title-bold}}
|
||||
(str (cond approve?
|
||||
(i18n/label :t/authorize)
|
||||
cancel?
|
||||
(i18n/label :t/cancelling)
|
||||
:else
|
||||
(i18n/label :t/sending))
|
||||
(if cancel?
|
||||
(str " " (utils/get-shortened-address (:hash tx)))
|
||||
(str " " amount " " display-symbol)))]
|
||||
[react/text {:style {:typography :title-bold}} (i18n/label :t/contract-interaction)])
|
||||
(if sign
|
||||
[react/nested-text
|
||||
{:style {:color colors/gray}
|
||||
:ellipsize-mode :middle
|
||||
:number-of-lines 1} (i18n/label :t/to-capitalized) " "
|
||||
[{:style {:color colors/black}} (profile.utils/displayed-name contact)]]
|
||||
[react/text {:style {:margin-top 6 :color colors/gray}}
|
||||
(str fee " " fee-display-symbol " " (string/lower-case (i18n/label :t/network-fee)))])]
|
||||
[react/view {:padding-horizontal 24}
|
||||
[quo/button
|
||||
(merge {:type :secondary}
|
||||
(when-not in-progress? {:on-press #(re-frame/dispatch [:signing.ui/cancel-is-pressed])}))
|
||||
(i18n/label :t/cancel)]]])
|
||||
|
||||
(defn sign-with-keycard-button
|
||||
[amount-error gas-error]
|
||||
(let [disabled? (or amount-error gas-error)]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(when-not disabled?
|
||||
(re-frame/dispatch [:signing.ui/sign-with-keycard-pressed]))}
|
||||
[react/view (styles/sign-with-keycard-button disabled?)
|
||||
[react/text {:style (styles/sign-with-keycard-button-text disabled?)}
|
||||
(i18n/label :t/sign-with)]
|
||||
[react/view {:padding-right 16}
|
||||
[react/image
|
||||
{:source (resources/get-image :keycard-logo)
|
||||
:style (merge {:width 64
|
||||
:margin-bottom 7
|
||||
:height 26}
|
||||
(when (colors/dark?)
|
||||
{:tint-color colors/white-persist}))}]]]]))
|
||||
|
||||
(defn- signing-phrase-view
|
||||
[phrase]
|
||||
[react/view {:align-items :center}
|
||||
[react/text {:style {:color colors/gray :padding-bottom 8}} (i18n/label :t/signing-phrase)]
|
||||
[react/text phrase]])
|
||||
|
||||
(defn- keycard-view
|
||||
[_ phrase]
|
||||
[react/view
|
||||
[signing-phrase-view phrase]
|
||||
[react/view {:align-items :center :margin-top 16 :margin-bottom 40}
|
||||
[sign-with-keycard-button nil nil]]])
|
||||
|
||||
(defn- transaction-data-item
|
||||
[data]
|
||||
(let [text (types/clj->pretty-json data 2)]
|
||||
[react/view
|
||||
[react/text
|
||||
{:style {:font-size 17
|
||||
:line-height 20
|
||||
:margin-bottom 24}}
|
||||
text]]))
|
||||
|
||||
(views/defview transaction-data
|
||||
[]
|
||||
(views/letsubs
|
||||
[{:keys [formatted-data]} [:signing/sign]]
|
||||
[react/view {:style {:flex 1}}
|
||||
[react/view
|
||||
{:style {:margin-horizontal 24
|
||||
:margin-top 24}}
|
||||
[react/text
|
||||
{:style {:font-size 17
|
||||
:font-weight "700"}}
|
||||
(i18n/label :t/transaction-data)]]
|
||||
[react/scroll-view
|
||||
{:style {:flex 1
|
||||
:margin-horizontal 8
|
||||
:padding-horizontal 16
|
||||
:padding-vertical 10
|
||||
:margin-vertical 14}}
|
||||
[transaction-data-item formatted-data]]
|
||||
[separator]
|
||||
[react/view
|
||||
{:style {:margin-horizontal 8
|
||||
:margin-vertical 16}}
|
||||
[quo/button {:on-press #(re-frame/dispatch [:hide-popover])}
|
||||
(i18n/label :t/close)]]]))
|
||||
|
||||
(views/defview password-view
|
||||
[{:keys [type error in-progress? enabled?] :as sign}]
|
||||
(views/letsubs [phrase [:signing/phrase]]
|
||||
(case type
|
||||
:password
|
||||
[react/view {:padding-top 8 :padding-bottom 8}
|
||||
[signing-phrase-view phrase]
|
||||
[react/view
|
||||
{:padding-horizontal 16
|
||||
:padding-vertical 12}
|
||||
[quo/text-input
|
||||
{:secure-text-entry true
|
||||
:placeholder (i18n/label :t/enter-password)
|
||||
:on-change-text #(re-frame/dispatch [:signing.ui/password-is-changed
|
||||
(security/mask-data %)])
|
||||
:accessibility-label :enter-password-input
|
||||
:auto-capitalize :none
|
||||
:editable (not in-progress?)
|
||||
:error error
|
||||
:show-cancel false}]]
|
||||
[react/view {:align-items :center :height 60}
|
||||
(if in-progress?
|
||||
[react/activity-indicator
|
||||
{:animating true
|
||||
:size :large}]
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [:signing.ui/sign-is-pressed])
|
||||
:disabled (not enabled?)}
|
||||
(i18n/label :t/transactions-sign)])]]
|
||||
:keycard
|
||||
[keycard-view sign phrase]
|
||||
[react/view])))
|
||||
|
||||
(views/defview message-sheet
|
||||
[]
|
||||
(views/letsubs [{:keys [formatted-data] :as sign} [:signing/sign-message]]
|
||||
[react/view (styles/message)
|
||||
[react/view styles/message-header
|
||||
[react/text {:style {:typography :title-bold}} (i18n/label :t/signing-a-message)]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:signing.ui/cancel-is-pressed])}
|
||||
[react/view {:padding 6}
|
||||
[react/text {:style {:color colors/blue}} (i18n/label :t/cancel)]]]]
|
||||
[separator]
|
||||
[react/view {:padding-top 16 :flex 1}
|
||||
[react/view styles/message-border
|
||||
[react/scroll-view
|
||||
[react/text (or formatted-data "")]]]
|
||||
[password-view sign]]]))
|
||||
|
||||
(defn error-item
|
||||
[]
|
||||
(fn [title show-error]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(swap! show-error not)
|
||||
:underlay-color (:interactive-02 @colors/theme)}
|
||||
[react/view
|
||||
{:style {:align-items :center
|
||||
:flex-direction :row}}
|
||||
[react/text {:style {:color colors/red :margin-right 8}}
|
||||
(i18n/label title)]
|
||||
[icons/icon :warning {:color colors/red}]]]))
|
||||
|
||||
(defn amount-item
|
||||
[]
|
||||
(let [show-error (reagent/atom false)]
|
||||
(fn [prices wallet-currency amount amount-error display-symbol fee-display-symbol prices-loading?]
|
||||
(let [converted-value (* amount
|
||||
(get-in prices
|
||||
[(keyword display-symbol) (keyword (:code wallet-currency))]))]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (if amount-error
|
||||
[error-item :t/send-request-amount show-error]
|
||||
(i18n/label :t/send-request-amount))
|
||||
:error (when (and amount-error @show-error) amount-error)
|
||||
:animated false
|
||||
:accessory [react/view {:style {:flex-direction :row}}
|
||||
[react/nested-text {:style {:color colors/gray}}
|
||||
[{:style {:color colors/black}} (utils/format-decimals amount 6)]
|
||||
" "
|
||||
(or display-symbol fee-display-symbol)
|
||||
" • "]
|
||||
(if prices-loading?
|
||||
[react/small-loading-indicator]
|
||||
[react/text {:style {:color colors/black}}
|
||||
(i18n/format-currency converted-value (:code wallet-currency))])
|
||||
[react/text {:style {:color colors/gray}} (str " " (:code wallet-currency))]]}]))))
|
||||
|
||||
(views/defview fee-item
|
||||
[prices wallet-currency fee-display-symbol fee
|
||||
insufficient-balance? gas-error gas-error-state prices-loading?]
|
||||
(views/letsubs [{:keys [gas-price-loading? gas-loading?]} [:signing/edit-fee]
|
||||
show-error (reagent/atom false)]
|
||||
(let [converted-fee-value (* fee
|
||||
(get-in prices
|
||||
[(keyword fee-display-symbol)
|
||||
(keyword (:code wallet-currency))]))]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (if (and (not (or gas-price-loading? gas-loading?)) gas-error)
|
||||
[error-item :t/network-fee show-error]
|
||||
(i18n/label :t/network-fee))
|
||||
:error (when (and (not (or gas-price-loading? gas-loading?)) gas-error @show-error)
|
||||
gas-error)
|
||||
:disabled (or insufficient-balance? gas-price-loading? gas-loading?)
|
||||
:chevron (not insufficient-balance?)
|
||||
:animated false
|
||||
:accessory (when-not insufficient-balance?
|
||||
(if (or gas-price-loading? gas-loading?)
|
||||
[react/small-loading-indicator]
|
||||
(if (= :gas-isnt-set gas-error-state)
|
||||
[react/text
|
||||
{:style {:color colors/blue}
|
||||
:accessibility-label :custom-gas-fee}
|
||||
(i18n/label :t/set-custom-fee)]
|
||||
[react/view
|
||||
{:style {:flex-direction :row}
|
||||
:accessibility-label :custom-gas-fee}
|
||||
[react/nested-text {:style {:color colors/gray}}
|
||||
[{:style {:color colors/black}} (utils/format-decimals fee 6)]
|
||||
" "
|
||||
fee-display-symbol
|
||||
" • "]
|
||||
(if prices-loading?
|
||||
[react/small-loading-indicator]
|
||||
[react/text {:style {:color colors/black}}
|
||||
(i18n/format-currency converted-fee-value (:code wallet-currency))])
|
||||
[react/text {:style {:color colors/gray}}
|
||||
(str " " (:code wallet-currency))]])))
|
||||
:on-press #(re-frame/dispatch
|
||||
[:signing.ui/open-fee-sheet
|
||||
{:content (fn []
|
||||
(if (eip1559/enabled?)
|
||||
[sheets/fee-bottom-sheet-eip1559-custom fee-display-symbol]
|
||||
[sheets/fee-bottom-sheet fee-display-symbol]))}])}])))
|
||||
|
||||
(views/defview network-item
|
||||
[]
|
||||
(views/letsubs [network-name [:network-name]]
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/network)
|
||||
:size :small
|
||||
:accessory :text
|
||||
:accessory-text network-name}]))
|
||||
|
||||
(defn advanced-item
|
||||
[]
|
||||
[:<>
|
||||
[separator]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/advanced)
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old {:content sheets/advanced}])}]])
|
||||
|
||||
(views/defview sheet
|
||||
[{:keys [from contact amount token cancel?] :as tx}]
|
||||
(views/letsubs [fee [:signing/fee]
|
||||
sign [:signing/sign]
|
||||
{:keys [amount-error gas-error gas-error-state insufficient-balalce?]}
|
||||
[:signing/amount-errors (:address from)]
|
||||
keycard-multiaccount? [:keycard-multiaccount?]
|
||||
prices [:prices]
|
||||
wallet-currency [:wallet-legacy/currency]
|
||||
mainnet? [:mainnet?]
|
||||
prices-loading? [:prices-loading?]
|
||||
management-enabled? [:wallet-legacy/transactions-management-enabled?]]
|
||||
(let [display-symbol nil
|
||||
fee-display-symbol nil]
|
||||
[react/view (styles/sheet)
|
||||
[header sign tx display-symbol fee fee-display-symbol]
|
||||
[separator]
|
||||
(if sign
|
||||
[react/view {:padding-top 20}
|
||||
[password-view sign]]
|
||||
[react/view
|
||||
(when-not mainnet?
|
||||
[react/view
|
||||
[network-item]
|
||||
[separator]])
|
||||
[contact-item (i18n/label :t/from-capitalized) from]
|
||||
[separator]
|
||||
[contact-item (i18n/label :t/to-capitalized) contact]
|
||||
(when-not cancel?
|
||||
[separator])
|
||||
(when-not cancel?
|
||||
[token-item token display-symbol])
|
||||
(when-not cancel?
|
||||
[amount-item prices wallet-currency amount amount-error display-symbol fee-display-symbol
|
||||
prices-loading?])
|
||||
[separator]
|
||||
[fee-item prices wallet-currency fee-display-symbol fee insufficient-balalce? gas-error
|
||||
gas-error-state prices-loading?]
|
||||
(when (and management-enabled? (not keycard-multiaccount?))
|
||||
[advanced-item])
|
||||
(when (= :gas-is-set gas-error-state)
|
||||
[react/text {:style {:color colors/gray :margin-horizontal 32 :text-align :center}}
|
||||
(i18n/label :t/tx-fail-description1)])
|
||||
[react/view {:align-items :center :margin-top 16 :margin-bottom 40}
|
||||
(if keycard-multiaccount?
|
||||
[sign-with-keycard-button amount-error gas-error]
|
||||
(if (= :gas-isnt-set gas-error-state)
|
||||
[react/text {:style {:color colors/gray :margin-horizontal 32 :text-align :center}}
|
||||
(i18n/label :t/tx-fail-description2)]
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [:set :signing/sign {:type :password}])
|
||||
:disabled (or amount-error gas-error)
|
||||
:theme (if gas-error-state :negative :main)}
|
||||
(i18n/label (if gas-error-state
|
||||
:t/sign-anyway
|
||||
:t/sign-with-password))]))]])])))
|
||||
|
||||
(views/defview signing
|
||||
[]
|
||||
(views/letsubs [tx [:signing/tx]]
|
||||
[bottom-panel/animated-bottom-panel
|
||||
;;we use select-keys here because we don't want to update view if other keys in map are changed
|
||||
(when tx (select-keys tx [:from :contact :amount :token :approve? :message :cancel? :hash]))
|
||||
#(if (:message %)
|
||||
[message-sheet]
|
||||
[sheet %])
|
||||
#(re-frame/dispatch [:hide-signing-sheet])]))
|
|
@ -104,62 +104,6 @@
|
|||
[chain]
|
||||
(get-in default-multiaccount [:wallet-legacy/visible-tokens chain]))
|
||||
|
||||
(def mainnet-networks
|
||||
[{:id "mainnet_rpc"
|
||||
:chain-explorer-link mainnet-chain-explorer-link
|
||||
:name "Mainnet with upstream RPC"
|
||||
:config {:NetworkId (chain/chain-keyword->chain-id :mainnet)
|
||||
:DataDir "/ethereum/mainnet_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL mainnet-rpc-url}}}])
|
||||
|
||||
(def sidechain-networks
|
||||
[{:id "xdai_rpc"
|
||||
:name "xDai Chain"
|
||||
:chain-explorer-link "https://blockscout.com/xdai/mainnet/address/"
|
||||
:config {:NetworkId (chain/chain-keyword->chain-id :xdai)
|
||||
:DataDir "/ethereum/xdai_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL "https://gnosischain-rpc.gateway.pokt.network"}}}
|
||||
{:id "bsc_rpc"
|
||||
:chain-explorer-link "https://bscscan.com/address/"
|
||||
:name "BSC Network"
|
||||
:config {:NetworkId (chain/chain-keyword->chain-id :bsc)
|
||||
:DataDir "/ethereum/bsc_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL "https://bsc-dataseed.binance.org"}}}])
|
||||
|
||||
(def testnet-networks
|
||||
[{:id "goerli_rpc"
|
||||
:chain-explorer-link "https://goerli.etherscan.io/address/"
|
||||
:name "Goerli with upstream RPC"
|
||||
:config {:NetworkId (chain/chain-keyword->chain-id :goerli)
|
||||
:DataDir "/ethereum/goerli_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL goerli-rpc-url}}}
|
||||
{:id "bsc_testnet_rpc"
|
||||
:chain-explorer-link "https://testnet.bscscan.com/address/"
|
||||
:name "BSC testnet"
|
||||
:config {:NetworkId (chain/chain-keyword->chain-id :bsc-testnet)
|
||||
:DataDir "/ethereum/bsc_testnet_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL "https://data-seed-prebsc-1-s1.binance.org:8545/"}}}])
|
||||
|
||||
(def default-networks
|
||||
(concat testnet-networks mainnet-networks sidechain-networks))
|
||||
|
||||
(def default-networks-by-id
|
||||
(into {}
|
||||
(map (fn [{:keys [id] :as network}]
|
||||
[id network])
|
||||
default-networks)))
|
||||
|
||||
(def default-network-id
|
||||
(get-in default-networks-by-id [default-network :config :NetworkId]))
|
||||
|
||||
(def default-network-rpc-url
|
||||
(get-in default-networks-by-id [default-network :config :UpstreamConfig :URL]))
|
||||
|
||||
(def waku-nodes-config
|
||||
{:status.prod
|
||||
["enrtree://AL65EKLJAUXKKPG43HVTML5EFFWEZ7L4LOKTLZCLJASG4DSESQZEC@prod.status.nodes.status.im"]
|
||||
|
|
|
@ -40,9 +40,6 @@
|
|||
:verifyENSURL config/verify-ens-url
|
||||
:verifyENSContractAddress config/verify-ens-contract-address
|
||||
:verifyTransactionChainID config/verify-transaction-chain-id
|
||||
:upstreamConfig config/default-network-rpc-url
|
||||
:networkId config/default-network-id
|
||||
:currentNetwork config/default-network
|
||||
:wakuV2LightClient false
|
||||
:previewPrivacy config/blank-preview?
|
||||
:testNetworksEnabled config/test-networks-enabled?})))
|
||||
|
|
|
@ -39,19 +39,17 @@
|
|||
;; login phase 1: we want to load and show chats faster, so we split login into 2 phases
|
||||
(rf/reg-event-fx :profile.login/login-existing-profile
|
||||
(fn [{:keys [db]} [settings account]]
|
||||
(let [{:networks/keys [current-network networks]
|
||||
(let [{:networks/keys [_current-network _networks]
|
||||
:as settings}
|
||||
(data-store.settings/rpc->settings settings)
|
||||
profile-overview (profile.rpc/rpc->profiles-overview account)
|
||||
log-level (or (:log-level settings) config/log-level)
|
||||
pairing-completed? (= (get-in db [:syncing :pairing-status]) :completed)]
|
||||
{:db (cond-> (-> db
|
||||
(assoc :chats/loading? true
|
||||
:networks/current-network current-network
|
||||
:networks/networks (merge networks config/default-networks-by-id)
|
||||
:profile/profile (merge profile-overview
|
||||
settings
|
||||
{:log-level log-level}))
|
||||
(assoc :chats/loading? true
|
||||
:profile/profile (merge profile-overview
|
||||
settings
|
||||
{:log-level log-level}))
|
||||
(assoc-in [:activity-center :loading?] true))
|
||||
pairing-completed?
|
||||
(dissoc :syncing))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im.contexts.syncing.events
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.data-store.settings :as data-store.settings]
|
||||
[legacy.status-im.node.core :as node]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
|
@ -26,14 +25,12 @@
|
|||
|
||||
(defn- get-default-node-config
|
||||
[installation-id]
|
||||
(let [db {:networks/current-network config/default-network
|
||||
:networks/networks (data-store.settings/rpc->networks config/default-networks)
|
||||
:profile/profile {:installation-id installation-id
|
||||
:device-name (native-module/get-installation-name)
|
||||
:log-level config/log-level
|
||||
:waku-bloom-filter-mode false
|
||||
:custom-bootnodes nil
|
||||
:custom-bootnodes-enabled? false}}]
|
||||
(let [db {:profile/profile {:installation-id installation-id
|
||||
:device-name (native-module/get-installation-name)
|
||||
:log-level config/log-level
|
||||
:waku-bloom-filter-mode false
|
||||
:custom-bootnodes nil
|
||||
:custom-bootnodes-enabled? false}}]
|
||||
(node/get-multiaccount-node-config db)))
|
||||
|
||||
(defn- extract-error
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im.events
|
||||
(:require
|
||||
[legacy.status-im.bottom-sheet.events]
|
||||
[legacy.status-im.keycard.core :as keycard]
|
||||
status-im.common.alert-banner.events
|
||||
status-im.common.alert.effects
|
||||
status-im.common.async-storage.effects
|
||||
|
@ -52,5 +51,4 @@
|
|||
;;app starting flow continues in get-profiles-overview
|
||||
:profile/get-profiles-overview #(rf/dispatch [:profile/get-profiles-overview-success %])
|
||||
:effects.font/get-font-file-for-initials-avatar
|
||||
#(rf/dispatch [:font/init-font-file-for-initials-avatar %])}
|
||||
(keycard/init)))
|
||||
#(rf/dispatch [:font/init-font-file-for-initials-avatar %])}))
|
||||
|
|
|
@ -1745,7 +1745,6 @@
|
|||
"empty-tab": "Empty tab",
|
||||
"open-in-new-tab": "Open in new tab",
|
||||
"has-permissions": "has permission to access",
|
||||
"connect-wallet": "Connect wallet",
|
||||
"open-chat": "Open chat",
|
||||
"favourite-description": "Your favourite websites will appear here",
|
||||
"transfers-fetching-failure": "Transfers history could not be updated. Check your connection and pull down to try again",
|
||||
|
|
Loading…
Reference in New Issue