chore: remove old wallet code, signing code and keycard code (#19467)

This commit is contained in:
Jamie Caprani 2024-04-10 18:41:24 +01:00 committed by GitHub
parent ce7912632c
commit 63a168b6f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
56 changed files with 57 additions and 7644 deletions

View File

@ -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)))

View File

@ -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")))))))

View File

@ -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]}

View File

@ -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]})

View File

@ -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.")}}})))

View File

@ -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

View File

@ -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

View File

@ -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)))

View File

@ -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)))))))

View File

@ -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))))))

View File

@ -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]))

View File

@ -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})))))

View File

@ -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})

View File

@ -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"}))

View File

@ -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)))

View File

@ -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))))

View File

@ -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)

View File

@ -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))

View File

@ -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)})))

View File

@ -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?)

View File

@ -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)))

View File

@ -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)}))

View File

@ -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))))))

View File

@ -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)))

View File

@ -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]])

View File

@ -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)))))

View File

@ -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))))

View File

@ -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}))})))

View File

@ -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}}))))))))))

View File

@ -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)))

View File

@ -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 %])})))

View File

@ -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)))))))

View File

@ -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 %)))))

View File

@ -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))))

View File

@ -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?)

View File

@ -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)

View File

@ -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))

View File

@ -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)]}]])))

View File

@ -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})

View File

@ -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}]]]))

View File

@ -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

View File

@ -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\"}"])}])])))
])))

View File

@ -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])]]]])))})))

View File

@ -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)]]]]))))

View File

@ -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

View File

@ -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)

View File

@ -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}}

View File

@ -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)]]])))

View File

@ -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})

View File

@ -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])]))

View File

@ -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"]

View File

@ -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?})))

View File

@ -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))

View File

@ -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

View File

@ -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 %])}))

View File

@ -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",