chore: remove legacy wallet code (#18749)
This commit is contained in:
parent
b0133e97cf
commit
42d2690c85
|
@ -1,7 +1,6 @@
|
||||||
(ns legacy.status-im.currency.core
|
(ns legacy.status-im.currency.core
|
||||||
(:require
|
(:require
|
||||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||||
[legacy.status-im.wallet.prices :as prices]
|
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn get-currency
|
(defn get-currency
|
||||||
|
@ -16,5 +15,4 @@
|
||||||
:currency
|
:currency
|
||||||
currency
|
currency
|
||||||
;; on changing currency, we should fetch tokens prices again
|
;; on changing currency, we should fetch tokens prices again
|
||||||
{:on-success #(rf/dispatch [:wallet/get-wallet-token])})
|
{:on-success #(rf/dispatch [:wallet/get-wallet-token])})))
|
||||||
(prices/update-prices)))
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
[legacy.status-im.ethereum.ens :as ens]
|
[legacy.status-im.ethereum.ens :as ens]
|
||||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||||
[legacy.status-im.utils.random :as random]
|
[legacy.status-im.utils.random :as random]
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.navigation.events :as navigation]
|
[status-im.navigation.events :as navigation]
|
||||||
|
@ -126,7 +125,7 @@
|
||||||
{:events [::set-pub-key]}
|
{:events [::set-pub-key]}
|
||||||
[{:keys [db]}]
|
[{:keys [db]}]
|
||||||
(let [{:keys [username address custom-domain?]} (:ens/registration db)
|
(let [{:keys [username address custom-domain?]} (:ens/registration db)
|
||||||
address (or address (wallet.utils/default-address db))
|
address address
|
||||||
{:keys [public-key]} (:profile/profile db)
|
{:keys [public-key]} (:profile/profile db)
|
||||||
chain-id (chain/chain-id db)
|
chain-id (chain/chain-id db)
|
||||||
username (fullname custom-domain? username)]
|
username (fullname custom-domain? username)]
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
[legacy.status-im.ethereum.decode :as decode]
|
[legacy.status-im.ethereum.decode :as decode]
|
||||||
[legacy.status-im.ethereum.encode :as encode]
|
[legacy.status-im.ethereum.encode :as encode]
|
||||||
[legacy.status-im.utils.mobile-sync :as utils.mobile-sync]
|
[legacy.status-im.utils.mobile-sync :as utils.mobile-sync]
|
||||||
[legacy.status-im.wallet.core :as wallet]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.common.json-rpc.events :as json-rpc]
|
[status-im.common.json-rpc.events :as json-rpc]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
|
@ -256,24 +255,13 @@
|
||||||
(let [checksum (eip55/address->checksum address)
|
(let [checksum (eip55/address->checksum address)
|
||||||
max-known-block (get-max-block-with-transfers db address)
|
max-known-block (get-max-block-with-transfers db address)
|
||||||
effects (cond-> [(when (seq transfers)
|
effects (cond-> [(when (seq transfers)
|
||||||
(set-lowest-fetched-block checksum transfers))
|
(set-lowest-fetched-block checksum transfers))]
|
||||||
(wallet/set-max-block-with-transfers checksum transfers)]
|
|
||||||
|
|
||||||
(seq transfers)
|
(seq transfers)
|
||||||
(concat
|
(concat
|
||||||
[]
|
[]
|
||||||
(mapv add-transfer transfers))
|
(mapv add-transfer transfers))
|
||||||
|
|
||||||
(and max-known-block
|
|
||||||
(some #(> (:block %) max-known-block) transfers))
|
|
||||||
(conj (wallet/update-balances
|
|
||||||
[address]
|
|
||||||
(zero? max-known-block)))
|
|
||||||
|
|
||||||
(and (zero? max-known-block)
|
|
||||||
(empty? transfers))
|
|
||||||
(conj (wallet/set-zero-balances {:address address}))
|
|
||||||
|
|
||||||
(< (count transfers) limit)
|
(< (count transfers) limit)
|
||||||
(conj (tx-history-end-reached checksum)))]
|
(conj (tx-history-end-reached checksum)))]
|
||||||
(apply rf/merge cofx (tx-fetching-ended [checksum]) effects)))
|
(apply rf/merge cofx (tx-fetching-ended [checksum]) effects)))
|
||||||
|
@ -282,8 +270,7 @@
|
||||||
{:events [::new-transfers]}
|
{:events [::new-transfers]}
|
||||||
[cofx transfers params]
|
[cofx transfers params]
|
||||||
(rf/merge cofx
|
(rf/merge cofx
|
||||||
(handle-new-transfer transfers params)
|
(handle-new-transfer transfers params)))
|
||||||
(wallet/stop-fetching-on-empty-tx-history transfers)))
|
|
||||||
|
|
||||||
(rf/defn tx-fetching-failed
|
(rf/defn tx-fetching-failed
|
||||||
{:events [::tx-fetching-failed]}
|
{:events [::tx-fetching-failed]}
|
||||||
|
|
|
@ -32,10 +32,6 @@
|
||||||
legacy.status-im.visibility-status-popover.core
|
legacy.status-im.visibility-status-popover.core
|
||||||
legacy.status-im.visibility-status-updates.core
|
legacy.status-im.visibility-status-updates.core
|
||||||
legacy.status-im.waku.core
|
legacy.status-im.waku.core
|
||||||
legacy.status-im.wallet.accounts.core
|
|
||||||
legacy.status-im.wallet.choose-recipient.core
|
|
||||||
[legacy.status-im.wallet.core :as wallet]
|
|
||||||
legacy.status-im.wallet.custom-tokens.core
|
|
||||||
[native-module.core :as native-module]
|
[native-module.core :as native-module]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
@ -141,7 +137,6 @@
|
||||||
(rf/merge cofx
|
(rf/merge cofx
|
||||||
{:db (dissoc db :app-in-background-since)}
|
{:db (dissoc db :app-in-background-since)}
|
||||||
(mailserver/process-next-messages-request)
|
(mailserver/process-next-messages-request)
|
||||||
(wallet/restart-wallet-service-after-background app-in-background-since)
|
|
||||||
(when-not new-account?
|
(when-not new-account?
|
||||||
(universal-links/process-stored-event))
|
(universal-links/process-stored-event))
|
||||||
#(when-let [chat-id (:current-chat-id db)]
|
#(when-let [chat-id (:current-chat-id db)]
|
||||||
|
@ -198,10 +193,8 @@
|
||||||
:reset-card (keycard/reset-card-screen-did-load %)
|
:reset-card (keycard/reset-card-screen-did-load %)
|
||||||
:enter-pin-settings (keycard/enter-pin-screen-did-load %)
|
:enter-pin-settings (keycard/enter-pin-screen-did-load %)
|
||||||
:keycard-login-pin (keycard/login-pin-screen-did-load %)
|
:keycard-login-pin (keycard/login-pin-screen-did-load %)
|
||||||
:add-new-account-pin (keycard/enter-pin-screen-did-load %)
|
|
||||||
:keycard-authentication-method (keycard/authentication-method-screen-did-load %)
|
:keycard-authentication-method (keycard/authentication-method-screen-did-load %)
|
||||||
:multiaccounts (keycard/multiaccounts-screen-did-load %)
|
:multiaccounts (keycard/multiaccounts-screen-did-load %)
|
||||||
:wallet-legacy (wallet/wallet-will-focus %)
|
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
;;TODO :replace by named events
|
;;TODO :replace by named events
|
||||||
|
|
|
@ -401,15 +401,12 @@
|
||||||
(merge
|
(merge
|
||||||
args
|
args
|
||||||
{:on-success
|
{:on-success
|
||||||
(fn [response]
|
(fn [_response]
|
||||||
(log/debug "[keycard response succ] export-key")
|
(log/debug "[keycard response succ] export-key")
|
||||||
(re-frame/dispatch [:keycard.callback/on-export-key-success
|
(js/alert "feature no longer supported"))
|
||||||
response]))
|
|
||||||
:on-failure
|
:on-failure
|
||||||
(fn [response]
|
(fn [_response]
|
||||||
(log/debug "[keycard response fail] export-key")
|
(log/debug "[keycard response fail] export-key"))})))
|
||||||
(re-frame/dispatch [:keycard.callback/on-export-key-error
|
|
||||||
(error-object->map response)]))})))
|
|
||||||
|
|
||||||
(defn unpair-and-delete
|
(defn unpair-and-delete
|
||||||
[args]
|
[args]
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
[legacy.status-im.keycard.recovery :as recovery]
|
[legacy.status-im.keycard.recovery :as recovery]
|
||||||
[legacy.status-im.keycard.sign :as sign]
|
[legacy.status-im.keycard.sign :as sign]
|
||||||
legacy.status-im.keycard.unpair
|
legacy.status-im.keycard.unpair
|
||||||
[legacy.status-im.keycard.wallet :as wallet]
|
|
||||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||||
[re-frame.db]
|
[re-frame.db]
|
||||||
[status-im.navigation.events :as navigation]
|
[status-im.navigation.events :as navigation]
|
||||||
|
@ -401,10 +400,6 @@
|
||||||
(= pin-code-length numbers-entered))
|
(= pin-code-length numbers-entered))
|
||||||
(common/verify-pin {:pin-step :current})
|
(common/verify-pin {:pin-step :current})
|
||||||
|
|
||||||
(and (= enter-step :export-key)
|
|
||||||
(= pin-code-length numbers-entered))
|
|
||||||
(wallet/verify-pin-with-delay)
|
|
||||||
|
|
||||||
(and (= enter-step :sign)
|
(and (= enter-step :sign)
|
||||||
(= pin-code-length numbers-entered))
|
(= pin-code-length numbers-entered))
|
||||||
(sign/prepare-to-sign)
|
(sign/prepare-to-sign)
|
||||||
|
|
|
@ -1,51 +1,13 @@
|
||||||
(ns legacy.status-im.keycard.export-key
|
(ns legacy.status-im.keycard.export-key
|
||||||
(:require
|
(:require
|
||||||
[legacy.status-im.keycard.common :as common]
|
[legacy.status-im.keycard.common :as common]
|
||||||
[legacy.status-im.keycard.wallet :as wallet]
|
|
||||||
[taoensso.timbre :as log]
|
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(rf/defn on-export-key-error
|
|
||||||
{:events [:keycard.callback/on-export-key-error]}
|
|
||||||
[{:keys [db] :as cofx} error]
|
|
||||||
(log/debug "[keycard] export key error" error)
|
|
||||||
(let [tag-was-lost? (common/tag-lost? (:error error))
|
|
||||||
pin-retries (common/pin-retries (:error error))]
|
|
||||||
(cond
|
|
||||||
tag-was-lost?
|
|
||||||
(rf/merge cofx
|
|
||||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
|
||||||
(common/set-on-card-connected :wallet-legacy.accounts/generate-new-keycard-account))
|
|
||||||
|
|
||||||
(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 :export-key
|
|
||||||
:puk []
|
|
||||||
:current []
|
|
||||||
:original []
|
|
||||||
:confirmation []
|
|
||||||
:sign []
|
|
||||||
:export-key []
|
|
||||||
:error-label :t/pin-mismatch))}
|
|
||||||
(common/hide-connection-sheet)
|
|
||||||
(when (zero? pin-retries) (common/frozen-keycard-popup)))
|
|
||||||
:else
|
|
||||||
(rf/merge cofx
|
|
||||||
(common/show-wrong-keycard-alert)
|
|
||||||
(common/clear-pin)
|
|
||||||
(common/hide-connection-sheet)))))
|
|
||||||
|
|
||||||
(rf/defn on-export-key-success
|
(rf/defn on-export-key-success
|
||||||
{:events [:keycard.callback/on-export-key-success]}
|
{:events [:keycard.callback/on-export-key-success]}
|
||||||
[{:keys [db] :as cofx} pubkey]
|
[{:keys [db] :as cofx} pubkey]
|
||||||
(let [callback-fn (get-in db [:keycard :on-export-success])]
|
(let [callback-fn (get-in db [:keycard :on-export-success])]
|
||||||
(rf/merge cofx
|
(rf/merge cofx
|
||||||
{:dispatch (callback-fn pubkey)}
|
{:dispatch (callback-fn pubkey)}
|
||||||
(wallet/hide-pin-sheet)
|
|
||||||
(common/clear-pin)
|
(common/clear-pin)
|
||||||
(common/hide-connection-sheet))))
|
(common/hide-connection-sheet))))
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[legacy.status-im.keycard.common :as common]
|
[legacy.status-im.keycard.common :as common]
|
||||||
[legacy.status-im.utils.deprecated-types :as types]
|
[legacy.status-im.utils.deprecated-types :as types]
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.address :as address]
|
[utils.address :as address]
|
||||||
|
@ -24,8 +23,7 @@
|
||||||
typed? (get-in db [:keycard :typed?])
|
typed? (get-in db [:keycard :typed?])
|
||||||
pin (common/vector->string (get-in db [:keycard :pin :sign]))
|
pin (common/vector->string (get-in db [:keycard :pin :sign]))
|
||||||
from (or (get-in db [:signing/tx :from :address])
|
from (or (get-in db [:signing/tx :from :address])
|
||||||
(get-in db [:signing/tx :message :from])
|
(get-in db [:signing/tx :message :from]))
|
||||||
(wallet.utils/default-address db))
|
|
||||||
path (reduce
|
path (reduce
|
||||||
(fn [_ {:keys [address path]}]
|
(fn [_ {:keys [address path]}]
|
||||||
(when (address/address= from address)
|
(when (address/address= from address)
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
(ns legacy.status-im.keycard.wallet
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
|
|
||||||
[legacy.status-im.keycard.common :as common]
|
|
||||||
[legacy.status-im.ui.screens.wallet.add-new.views :as add-new.views]
|
|
||||||
[legacy.status-im.utils.hex :as utils.hex]
|
|
||||||
[native-module.core :as native-module]
|
|
||||||
[status-im.constants :as constants]
|
|
||||||
[utils.ethereum.eip.eip55 :as eip55]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
(rf/defn show-pin-sheet
|
|
||||||
{:events [:keycard/new-account-pin-sheet]}
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(rf/merge
|
|
||||||
cofx
|
|
||||||
{:db (-> db
|
|
||||||
(assoc-in [:keycard :pin :enter-step] :export-key)
|
|
||||||
(update-in [:keycard :pin] dissoc :export-key))
|
|
||||||
:dismiss-keyboard nil}
|
|
||||||
(bottom-sheet/show-bottom-sheet-old {:view {:content add-new.views/pin}})))
|
|
||||||
|
|
||||||
(rf/defn verify-pin-with-delay
|
|
||||||
[cofx]
|
|
||||||
{:utils/dispatch-later
|
|
||||||
;; We need to give previous sheet some time to be fully hidden
|
|
||||||
[{:ms 200
|
|
||||||
:dispatch [:wallet-legacy.accounts/verify-pin]}]})
|
|
||||||
|
|
||||||
(rf/defn hide-pin-sheet
|
|
||||||
{:events [:keycard/new-account-pin-sheet-hide]}
|
|
||||||
[cofx]
|
|
||||||
(bottom-sheet/hide-bottom-sheet-old cofx))
|
|
||||||
|
|
||||||
(defn public-key->address
|
|
||||||
[public-key]
|
|
||||||
(let [length (count public-key)
|
|
||||||
normalized-key (case length
|
|
||||||
132 (str "0x" (subs public-key 4))
|
|
||||||
130 public-key
|
|
||||||
128 (str "0x" public-key)
|
|
||||||
nil)]
|
|
||||||
(when normalized-key
|
|
||||||
(subs (native-module/sha3 normalized-key) 26))))
|
|
||||||
|
|
||||||
(rf/defn generate-new-keycard-account
|
|
||||||
{:events [:wallet-legacy.accounts/generate-new-keycard-account]}
|
|
||||||
[{:keys [db]}]
|
|
||||||
(let [path-num (inc (get-in db [:profile/profile :latest-derived-path]))
|
|
||||||
path (str constants/path-wallet-root "/" path-num)
|
|
||||||
pin (common/vector->string (get-in db [:keycard :pin :export-key]))]
|
|
||||||
{:db
|
|
||||||
(assoc-in
|
|
||||||
db
|
|
||||||
[:keycard :on-export-success]
|
|
||||||
#(vector :wallet-legacy.accounts/account-stored
|
|
||||||
(let [public-key (utils.hex/normalize-hex %)]
|
|
||||||
{;; Strip leading 04 prefix denoting uncompressed key format
|
|
||||||
:address (eip55/address->checksum
|
|
||||||
(str "0x"
|
|
||||||
(public-key->address
|
|
||||||
(subs public-key 2))))
|
|
||||||
:public-key (str "0x" public-key)
|
|
||||||
:path path})))
|
|
||||||
|
|
||||||
:keycard/export-key {:pin pin :path path}}))
|
|
||||||
|
|
||||||
(rf/defn verify-pin
|
|
||||||
{:events [:wallet-legacy.accounts/verify-pin]}
|
|
||||||
[cofx]
|
|
||||||
(common/verify-pin
|
|
||||||
cofx
|
|
||||||
{:pin-step :export-key
|
|
||||||
:on-card-connected :wallet-legacy.accounts/verify-pin
|
|
||||||
:on-success :wallet-legacy.accounts/generate-new-keycard-account
|
|
||||||
:on-failure :keycard/new-account-pin-sheet}))
|
|
|
@ -5,7 +5,6 @@
|
||||||
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
|
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
|
||||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||||
[legacy.status-im.utils.mobile-sync :as utils]
|
[legacy.status-im.utils.mobile-sync :as utils]
|
||||||
[legacy.status-im.wallet.core :as wallet]
|
|
||||||
[status-im.contexts.chat.home.add-new-contact.events :as add-new-contact]
|
[status-im.contexts.chat.home.add-new-contact.events :as add-new-contact]
|
||||||
[status-im.navigation.events :as navigation]
|
[status-im.navigation.events :as navigation]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
|
@ -35,7 +34,6 @@
|
||||||
(and logged-in? initialized?)
|
(and logged-in? initialized?)
|
||||||
[(mailserver/process-next-messages-request)
|
[(mailserver/process-next-messages-request)
|
||||||
(bottom-sheet/hide-bottom-sheet-old)
|
(bottom-sheet/hide-bottom-sheet-old)
|
||||||
(wallet/restart-wallet-service nil)
|
|
||||||
#(add-new-contact/set-new-identity-reconnected %)]
|
#(add-new-contact/set-new-identity-reconnected %)]
|
||||||
|
|
||||||
logged-in?
|
logged-in?
|
||||||
|
@ -67,8 +65,7 @@
|
||||||
(boolean remember-choice?)
|
(boolean remember-choice?)
|
||||||
{})
|
{})
|
||||||
(when (and cellular? sync?)
|
(when (and cellular? sync?)
|
||||||
(mailserver/process-next-messages-request))
|
(mailserver/process-next-messages-request)))))))
|
||||||
(wallet/restart-wallet-service nil))))))
|
|
||||||
|
|
||||||
(rf/defn mobile-network-continue-syncing
|
(rf/defn mobile-network-continue-syncing
|
||||||
{:events [:mobile-network/continue-syncing]}
|
{:events [:mobile-network/continue-syncing]}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
(ns legacy.status-im.multiaccounts.logout.core
|
(ns legacy.status-im.multiaccounts.logout.core
|
||||||
(:require
|
(:require
|
||||||
[legacy.status-im.wallet.core :as wallet]
|
|
||||||
[native-module.core :as native-module]
|
[native-module.core :as native-module]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.common.keychain.events :as keychain]
|
[status-im.common.keychain.events :as keychain]
|
||||||
|
@ -39,7 +38,6 @@
|
||||||
:profile/get-profiles-overview #(rf/dispatch
|
:profile/get-profiles-overview #(rf/dispatch
|
||||||
[:profile/get-profiles-overview-success %])}
|
[:profile/get-profiles-overview-success %])}
|
||||||
(keychain/save-auth-method key-uid auth-method)
|
(keychain/save-auth-method key-uid auth-method)
|
||||||
(wallet/clear-timeouts)
|
|
||||||
(initialize-app-db))))
|
(initialize-app-db))))
|
||||||
|
|
||||||
(rf/defn logout
|
(rf/defn logout
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
(:require
|
(:require
|
||||||
["@react-native-community/netinfo" :default net-info]
|
["@react-native-community/netinfo" :default net-info]
|
||||||
[legacy.status-im.mobile-sync-settings.core :as mobile-network]
|
[legacy.status-im.mobile-sync-settings.core :as mobile-network]
|
||||||
[legacy.status-im.wallet.core :as wallet]
|
|
||||||
[native-module.core :as native-module]
|
[native-module.core :as native-module]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
|
@ -11,12 +10,7 @@
|
||||||
(rf/defn change-network-status
|
(rf/defn change-network-status
|
||||||
[{:keys [db] :as cofx} is-connected?]
|
[{:keys [db] :as cofx} is-connected?]
|
||||||
(rf/merge cofx
|
(rf/merge cofx
|
||||||
{:db (assoc db :network-status (if is-connected? :online :offline))}
|
{:db (assoc db :network-status (if is-connected? :online :offline))}))
|
||||||
(when (and is-connected?
|
|
||||||
(or (not= (count (get-in db [:wallet-legacy :accounts]))
|
|
||||||
(count (get db :profile/wallet-accounts)))
|
|
||||||
(wallet/has-empty-balances? db)))
|
|
||||||
(wallet/update-balances nil nil))))
|
|
||||||
|
|
||||||
(rf/defn change-network-type
|
(rf/defn change-network-type
|
||||||
[{:keys [db] :as cofx} old-network-type network-type expensive?]
|
[{:keys [db] :as cofx} old-network-type network-type expensive?]
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
(ns legacy.status-im.search.core-test
|
|
||||||
(:require
|
|
||||||
[cljs.test :refer-macros [deftest testing is]]
|
|
||||||
[legacy.status-im.subs.wallet.search :as search.subs]))
|
|
||||||
|
|
||||||
(defn extract-chat-attributes
|
|
||||||
[chat]
|
|
||||||
(let [{:keys [name alias tags]} (val chat)]
|
|
||||||
(into [name alias] tags)))
|
|
||||||
|
|
||||||
(deftest filter-chats
|
|
||||||
(let [chats {:chat-1 {:name "name1"
|
|
||||||
:alias "alias1"
|
|
||||||
:tags #{"tag1"}}
|
|
||||||
:chat-2 {:name "name2"
|
|
||||||
:alias "alias2"
|
|
||||||
:tags #{"tag2" "tag3"}}
|
|
||||||
:chat-3 {:name "name3"
|
|
||||||
:alias "alias3"
|
|
||||||
:tags #{}}
|
|
||||||
:chat-4 {:name "name4"
|
|
||||||
:alias "alias4"
|
|
||||||
:tags #{"tag4"}}}]
|
|
||||||
(testing "no search filter"
|
|
||||||
(is (= (count chats)
|
|
||||||
(count (search.subs/apply-filter ""
|
|
||||||
chats
|
|
||||||
extract-chat-attributes
|
|
||||||
false)))))
|
|
||||||
(testing "searching for a specific tag"
|
|
||||||
(is (= 1
|
|
||||||
(count (search.subs/apply-filter "tag2"
|
|
||||||
chats
|
|
||||||
extract-chat-attributes
|
|
||||||
false)))))
|
|
||||||
(testing "searching for a partial tag"
|
|
||||||
(is (= 3
|
|
||||||
(count (search.subs/apply-filter "tag"
|
|
||||||
chats
|
|
||||||
extract-chat-attributes
|
|
||||||
false)))))
|
|
||||||
(testing "searching for a specific alias"
|
|
||||||
(is (= 1
|
|
||||||
(count (search.subs/apply-filter "alias4"
|
|
||||||
chats
|
|
||||||
extract-chat-attributes
|
|
||||||
false)))))
|
|
||||||
(testing "searching for a partial alias"
|
|
||||||
(is (= 4
|
|
||||||
(count (search.subs/apply-filter "alias"
|
|
||||||
chats
|
|
||||||
extract-chat-attributes
|
|
||||||
false)))))
|
|
||||||
(testing "searching for a specific chat name"
|
|
||||||
(is (= 1
|
|
||||||
(count (search.subs/apply-filter "name4"
|
|
||||||
chats
|
|
||||||
extract-chat-attributes
|
|
||||||
false)))))))
|
|
|
@ -10,9 +10,6 @@
|
||||||
[legacy.status-im.utils.deprecated-types :as types]
|
[legacy.status-im.utils.deprecated-types :as types]
|
||||||
[legacy.status-im.utils.hex :as utils.hex]
|
[legacy.status-im.utils.hex :as utils.hex]
|
||||||
[legacy.status-im.utils.utils :as utils]
|
[legacy.status-im.utils.utils :as utils]
|
||||||
[legacy.status-im.wallet.core :as wallet]
|
|
||||||
[legacy.status-im.wallet.prices :as prices]
|
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[native-module.core :as native-module]
|
[native-module.core :as native-module]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.common.json-rpc.events :as json-rpc]
|
[status-im.common.json-rpc.events :as json-rpc]
|
||||||
|
@ -83,7 +80,7 @@
|
||||||
[{{:signing/keys [sign tx] :as db} :db}]
|
[{{:signing/keys [sign tx] :as db} :db}]
|
||||||
(let [{{:keys [data typed? from v4]} :message} tx
|
(let [{{:keys [data typed? from v4]} :message} tx
|
||||||
{:keys [in-progress? password]} sign
|
{:keys [in-progress? password]} sign
|
||||||
from (or from (wallet.utils/default-address db))
|
from from
|
||||||
hashed-password (native-module/sha3 (security/safe-unmask-data
|
hashed-password (native-module/sha3 (security/safe-unmask-data
|
||||||
password))]
|
password))]
|
||||||
(when-not in-progress?
|
(when-not in-progress?
|
||||||
|
@ -335,7 +332,7 @@
|
||||||
:dismiss-keyboard nil}
|
:dismiss-keyboard nil}
|
||||||
#(when-not wallet-set-up-passed?
|
#(when-not wallet-set-up-passed?
|
||||||
{:dispatch-later [{:dispatch [:show-popover {:view :signing-phrase}] :ms 200}]})
|
{:dispatch-later [{:dispatch [:show-popover {:view :signing-phrase}] :ms 200}]})
|
||||||
(prices/update-prices)
|
|
||||||
#(when-not gas
|
#(when-not gas
|
||||||
{:db (assoc-in (:db %) [:signing/edit-fee :gas-loading?] true)
|
{:db (assoc-in (:db %) [:signing/edit-fee :gas-loading?] true)
|
||||||
:signing/update-estimated-gas {:obj (-> tx-obj
|
:signing/update-estimated-gas {:obj (-> tx-obj
|
||||||
|
@ -395,7 +392,6 @@
|
||||||
:signing/show-transaction-result nil}
|
:signing/show-transaction-result nil}
|
||||||
(prepare-unconfirmed-transaction result tx-obj symbol amount)
|
(prepare-unconfirmed-transaction result tx-obj symbol amount)
|
||||||
(check-queue)
|
(check-queue)
|
||||||
(wallet/watch-tx (get from :address) result)
|
|
||||||
#(when on-result
|
#(when on-result
|
||||||
{:dispatch (conj on-result result)}))))
|
{:dispatch (conj on-result result)}))))
|
||||||
|
|
||||||
|
@ -408,7 +404,6 @@
|
||||||
(rf/merge
|
(rf/merge
|
||||||
cofx
|
cofx
|
||||||
{:db (dissoc db :signing/tx :signing/sign)}
|
{:db (dissoc db :signing/tx :signing/sign)}
|
||||||
(wallet/watch-tx (get from :address) transaction-hash)
|
|
||||||
(if (keycard.common/keycard-multiaccount? db)
|
(if (keycard.common/keycard-multiaccount? db)
|
||||||
(signing.keycard/hash-message
|
(signing.keycard/hash-message
|
||||||
{:data data
|
{:data data
|
||||||
|
@ -511,8 +506,8 @@
|
||||||
{:dispatch (conj on-error "transaction was cancelled by user")}))))
|
{:dispatch (conj on-error "transaction was cancelled by user")}))))
|
||||||
|
|
||||||
(defn normalize-tx-obj
|
(defn normalize-tx-obj
|
||||||
[db tx]
|
[_db tx]
|
||||||
(update-in tx [:tx-obj :from] #(eip55/address->checksum (or % (wallet.utils/default-address db)))))
|
(update-in tx [:tx-obj :from] #(eip55/address->checksum %)))
|
||||||
|
|
||||||
(rf/defn sign
|
(rf/defn sign
|
||||||
"Signing transaction or message, shows signing sheet
|
"Signing transaction or message, shows signing sheet
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns legacy.status-im.stickers.core
|
(ns legacy.status-im.stickers.core
|
||||||
(:require
|
(:require
|
||||||
[legacy.status-im.utils.utils :as utils]
|
[legacy.status-im.utils.utils :as utils]
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[utils.ethereum.chain :as chain]
|
[utils.ethereum.chain :as chain]
|
||||||
|
@ -39,15 +38,6 @@
|
||||||
:params []
|
:params []
|
||||||
:on-success #(re-frame/dispatch [:stickers/stickers-recent-success %])}]})
|
:on-success #(re-frame/dispatch [:stickers/stickers-recent-success %])}]})
|
||||||
|
|
||||||
(rf/defn buy-pack
|
|
||||||
{:events [:stickers/buy-pack]}
|
|
||||||
[{db :db} pack-id]
|
|
||||||
{:json-rpc/call [{:method "stickers_buyPrepareTx"
|
|
||||||
:params [(chain/chain-id db) (wallet.utils/default-address db) (int pack-id)]
|
|
||||||
:on-success #(re-frame/dispatch [:signing.ui/sign
|
|
||||||
{:tx-obj %
|
|
||||||
:on-result [:stickers/pending-pack pack-id]}])}]})
|
|
||||||
|
|
||||||
(rf/defn pending-pack
|
(rf/defn pending-pack
|
||||||
{:events [:stickers/pending-pack]}
|
{:events [:stickers/pending-pack]}
|
||||||
[{db :db} id]
|
[{db :db} id]
|
||||||
|
|
|
@ -7,10 +7,6 @@
|
||||||
legacy.status-im.subs.mailservers
|
legacy.status-im.subs.mailservers
|
||||||
legacy.status-im.subs.networks
|
legacy.status-im.subs.networks
|
||||||
legacy.status-im.subs.stickers
|
legacy.status-im.subs.stickers
|
||||||
legacy.status-im.subs.wallet.search
|
|
||||||
legacy.status-im.subs.wallet.signing
|
|
||||||
legacy.status-im.subs.wallet.transactions
|
|
||||||
legacy.status-im.subs.wallet.wallet
|
|
||||||
[re-frame.core :as re-frame]))
|
[re-frame.core :as re-frame]))
|
||||||
|
|
||||||
(defn reg-root-key-sub
|
(defn reg-root-key-sub
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
(ns legacy.status-im.subs.wallet.search
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.utils.currency :as currency]
|
|
||||||
[re-frame.core :as re-frame]))
|
|
||||||
|
|
||||||
(defn sort-by-timestamp
|
|
||||||
[coll]
|
|
||||||
(when (not-empty coll)
|
|
||||||
(sort-by #(-> % second :timestamp)
|
|
||||||
>
|
|
||||||
(into {} coll))))
|
|
||||||
|
|
||||||
(defn apply-filter
|
|
||||||
"extract-attributes-fn is a function that take an element from the collection
|
|
||||||
and returns a vector of attributes which are strings
|
|
||||||
apply-filter returns the elements for which at least one attribute includes
|
|
||||||
the search-filter
|
|
||||||
apply-filter returns nil if there is no element that match the filter
|
|
||||||
apply-filter returns full collection if the search-filter is empty"
|
|
||||||
[search-filter coll extract-attributes-fn sort?]
|
|
||||||
(let [results (if (not-empty search-filter)
|
|
||||||
(let [search-filter (string/lower-case search-filter)]
|
|
||||||
(filter (fn [element]
|
|
||||||
(some (fn [v]
|
|
||||||
(let [s (cond (string? v) v
|
|
||||||
(keyword? v) (name v))]
|
|
||||||
(when (string? s)
|
|
||||||
(string/includes? (string/lower-case s)
|
|
||||||
search-filter))))
|
|
||||||
(extract-attributes-fn element)))
|
|
||||||
coll))
|
|
||||||
coll)]
|
|
||||||
(if sort?
|
|
||||||
(sort-by-timestamp results)
|
|
||||||
results)))
|
|
||||||
|
|
||||||
(defn extract-currency-attributes
|
|
||||||
[currency]
|
|
||||||
(let [{:keys [code display-name]} (val currency)]
|
|
||||||
[code display-name]))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/search-filtered-currencies
|
|
||||||
:<- [:search/currency-filter]
|
|
||||||
(fn [search-currency-filter]
|
|
||||||
{:search-filter search-currency-filter
|
|
||||||
:currencies (apply-filter search-currency-filter
|
|
||||||
currency/currencies
|
|
||||||
extract-currency-attributes
|
|
||||||
false)}))
|
|
||||||
|
|
||||||
(defn extract-token-attributes
|
|
||||||
[token]
|
|
||||||
[(:symbol token) (:name token)])
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/search-token-filter
|
|
||||||
:<- [:ui/search]
|
|
||||||
(fn [search]
|
|
||||||
(get search :token-filter)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/filtered-grouped-chain-tokens
|
|
||||||
:<- [:wallet-legacy/grouped-chain-tokens]
|
|
||||||
:<- [:wallet-legacy/search-token-filter]
|
|
||||||
(fn [[{custom-tokens true default-tokens nil} search-token-filter]]
|
|
||||||
{:search-filter search-token-filter
|
|
||||||
:tokens {true (apply-filter search-token-filter custom-tokens extract-token-attributes false)
|
|
||||||
nil (apply-filter search-token-filter
|
|
||||||
default-tokens
|
|
||||||
extract-token-attributes
|
|
||||||
false)}}))
|
|
|
@ -1,235 +0,0 @@
|
||||||
(ns legacy.status-im.subs.wallet.signing
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ethereum.tokens :as tokens]
|
|
||||||
[legacy.status-im.signing.gas :as signing.gas]
|
|
||||||
[legacy.status-im.wallet.db :as wallet.db]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[utils.ethereum.chain :as chain]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.money :as money]))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
::send-transaction
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet]
|
|
||||||
(:send-transaction wallet)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.send/symbol
|
|
||||||
:<- [::send-transaction]
|
|
||||||
(fn [send-transaction]
|
|
||||||
(:symbol send-transaction)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.send/camera-flashlight
|
|
||||||
:<- [::send-transaction]
|
|
||||||
(fn [send-transaction]
|
|
||||||
(:camera-flashlight send-transaction)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/settings
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [{:keys [settings]}]
|
|
||||||
(reduce-kv #(conj %1 %3) [] settings)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.request/transaction
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
:request-transaction)
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/binance-chain?
|
|
||||||
:<- [:current-network]
|
|
||||||
(fn [network]
|
|
||||||
(chain/binance-chain-id? (get-in network [:config :NetworkId]))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:signing/fee
|
|
||||||
:<- [:signing/tx]
|
|
||||||
(fn [{:keys [gas gasPrice maxFeePerGas]}]
|
|
||||||
(signing.gas/calculate-max-fee gas (or maxFeePerGas gasPrice))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:signing/currencies
|
|
||||||
:<- [:prices]
|
|
||||||
:<- [:wallet-legacy/currency]
|
|
||||||
:<- [:ethereum/native-currency]
|
|
||||||
(fn [[prices {:keys [code]} {sym :symbol}]]
|
|
||||||
[(name sym)
|
|
||||||
code
|
|
||||||
(get-in prices [sym (keyword code)])]))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:signing/priority-fee-suggestions-range
|
|
||||||
:<- [:wallet-legacy/current-priority-fee]
|
|
||||||
:<- [:wallet-legacy/slow-base-fee]
|
|
||||||
:<- [:wallet-legacy/normal-base-fee]
|
|
||||||
:<- [:wallet-legacy/fast-base-fee]
|
|
||||||
(fn [[latest-tip slow normal fast]]
|
|
||||||
(reduce
|
|
||||||
(fn [acc [k fees]]
|
|
||||||
(assoc acc
|
|
||||||
k
|
|
||||||
(reduce
|
|
||||||
(fn [acc [k fee]]
|
|
||||||
(assoc acc
|
|
||||||
k
|
|
||||||
(-> fee
|
|
||||||
money/wei->gwei
|
|
||||||
(money/to-fixed 2))))
|
|
||||||
{}
|
|
||||||
fees)))
|
|
||||||
{}
|
|
||||||
(signing.gas/get-fee-options latest-tip slow normal fast))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:signing/phrase
|
|
||||||
:<- [:profile/profile]
|
|
||||||
(fn [{:keys [signing-phrase]}]
|
|
||||||
signing-phrase))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:signing/sign-message
|
|
||||||
:<- [:signing/sign]
|
|
||||||
:<- [:profile/wallet-accounts]
|
|
||||||
:<- [:prices]
|
|
||||||
(fn [[sign wallet-accounts prices]]
|
|
||||||
(if (= :pinless (:type sign))
|
|
||||||
(let [message (get-in sign [:formatted-data :message])
|
|
||||||
wallet-acc (some #(when (= (:address %) (:receiver message)) %) wallet-accounts)]
|
|
||||||
(cond-> sign
|
|
||||||
(and (:amount message) (:currency message))
|
|
||||||
(assoc :fiat-amount
|
|
||||||
(money/fiat-amount-value (:amount message)
|
|
||||||
(:currency message)
|
|
||||||
:USD
|
|
||||||
prices)
|
|
||||||
:fiat-currency "USD")
|
|
||||||
(and (:receiver message) wallet-acc)
|
|
||||||
(assoc :account wallet-acc)))
|
|
||||||
sign)))
|
|
||||||
|
|
||||||
(defn- too-precise-amount?
|
|
||||||
"Checks if number has any extra digit beyond the allowed number of decimals.
|
|
||||||
It does so by checking the number against its rounded value."
|
|
||||||
[amount decimals]
|
|
||||||
(let [^js bn (money/bignumber amount)]
|
|
||||||
(not (.eq bn (.round bn decimals)))))
|
|
||||||
|
|
||||||
(defn get-amount-error
|
|
||||||
[amount decimals]
|
|
||||||
(when (and (seq amount) decimals)
|
|
||||||
(let [normalized-amount (money/normalize amount)
|
|
||||||
value (money/bignumber normalized-amount)]
|
|
||||||
(cond
|
|
||||||
(not (money/valid? value))
|
|
||||||
{:amount-error (i18n/label :t/validation-amount-invalid-number)}
|
|
||||||
|
|
||||||
(too-precise-amount? normalized-amount decimals)
|
|
||||||
{:amount-error (i18n/label :t/validation-amount-is-too-precise {:decimals decimals})}
|
|
||||||
|
|
||||||
:else nil))))
|
|
||||||
|
|
||||||
(defn get-sufficient-funds-error
|
|
||||||
[balance sym amount]
|
|
||||||
(when-not (money/sufficient-funds? amount (get balance sym))
|
|
||||||
{:amount-error (i18n/label :t/wallet-insufficient-funds)}))
|
|
||||||
|
|
||||||
(defn gas-required-exceeds-allowance?
|
|
||||||
[gas-error-message]
|
|
||||||
(and gas-error-message
|
|
||||||
(string/starts-with?
|
|
||||||
gas-error-message
|
|
||||||
"gas required exceeds allowance")))
|
|
||||||
|
|
||||||
(defn get-sufficient-gas-error
|
|
||||||
[gas-error-message balance sym amount ^js gas ^js gasPrice]
|
|
||||||
(if (and gas gasPrice)
|
|
||||||
(let [^js fee (.times gas gasPrice)
|
|
||||||
^js available-ether (money/bignumber (get balance :ETH 0))
|
|
||||||
^js available-for-gas (if (= :ETH sym)
|
|
||||||
(.minus available-ether (money/bignumber amount))
|
|
||||||
available-ether)]
|
|
||||||
(merge {:gas-error-state (when gas-error-message :gas-is-set)}
|
|
||||||
(when-not (money/sufficient-funds? fee (money/bignumber available-for-gas))
|
|
||||||
{:gas-error (i18n/label :t/wallet-insufficient-gas)})))
|
|
||||||
(let [insufficient-balance? (gas-required-exceeds-allowance? gas-error-message)]
|
|
||||||
{:gas-error-state (when gas-error-message :gas-isnt-set)
|
|
||||||
:insufficient-balalce? insufficient-balance?
|
|
||||||
:gas-error (if insufficient-balance?
|
|
||||||
(i18n/label :t/insufficient-balance-to-cover-fee)
|
|
||||||
(or gas-error-message
|
|
||||||
(i18n/label :t/invalid-number)))})))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:signing/amount-errors
|
|
||||||
(fn [[_ address] _]
|
|
||||||
[(re-frame/subscribe [:signing/tx])
|
|
||||||
(re-frame/subscribe [:balance address])])
|
|
||||||
(fn [[{:keys [amount token gas gasPrice maxFeePerGas approve? gas-error-message]} balance]]
|
|
||||||
(let [gas-price (or maxFeePerGas gasPrice)]
|
|
||||||
(if (and amount token (not approve?))
|
|
||||||
(let [amount-bn (money/formatted->internal (money/bignumber amount)
|
|
||||||
(:symbol token)
|
|
||||||
(:decimals token))
|
|
||||||
amount-error (or (get-amount-error amount (:decimals token))
|
|
||||||
(get-sufficient-funds-error balance (:symbol token) amount-bn))]
|
|
||||||
(merge
|
|
||||||
amount-error
|
|
||||||
(get-sufficient-gas-error gas-error-message balance (:symbol token) amount-bn gas gas-price)))
|
|
||||||
(get-sufficient-gas-error gas-error-message balance nil nil gas gas-price)))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.send/prepare-transaction-with-balance
|
|
||||||
:<- [:wallet-legacy/prepare-transaction]
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
:<- [:offline?]
|
|
||||||
:<- [:wallet-legacy/all-tokens]
|
|
||||||
:<- [:current-network]
|
|
||||||
(fn [[{:keys [from to amount-text] :as transaction}
|
|
||||||
wallet offline? all-tokens current-network]]
|
|
||||||
(let [sym (:symbol transaction)
|
|
||||||
balance (get-in wallet [:accounts (:address from) :balance])
|
|
||||||
{:keys [decimals] :as token} (tokens/asset-for all-tokens current-network sym)
|
|
||||||
{:keys [value error]} (wallet.db/parse-amount amount-text decimals)
|
|
||||||
amount (money/formatted->internal value sym decimals)
|
|
||||||
{:keys [amount-error] :as transaction-new}
|
|
||||||
(merge transaction
|
|
||||||
{:amount-error error}
|
|
||||||
(when amount
|
|
||||||
(get-sufficient-funds-error balance sym amount)))]
|
|
||||||
(assoc transaction-new
|
|
||||||
:amount amount
|
|
||||||
:balance balance
|
|
||||||
:token (assoc token :amount (get balance (:symbol token)))
|
|
||||||
:sign-enabled? (and to
|
|
||||||
(nil? amount-error)
|
|
||||||
(not (nil? amount))
|
|
||||||
(not offline?))))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.request/prepare-transaction-with-balance
|
|
||||||
:<- [:wallet-legacy/prepare-transaction]
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
:<- [:offline?]
|
|
||||||
:<- [:wallet-legacy/all-tokens]
|
|
||||||
:<- [:current-network]
|
|
||||||
(fn [[{:keys [from to amount-text] :as transaction}
|
|
||||||
wallet offline? all-tokens current-network]]
|
|
||||||
(let [sym (:symbol transaction)
|
|
||||||
balance (get-in wallet [:accounts (:address from) :balance])
|
|
||||||
{:keys [decimals] :as token} (tokens/asset-for all-tokens current-network sym)
|
|
||||||
{:keys [value error]} (wallet.db/parse-amount amount-text decimals)
|
|
||||||
amount (money/formatted->internal value sym decimals)
|
|
||||||
{:keys [amount-error] :as transaction-new}
|
|
||||||
(assoc transaction :amount-error error)]
|
|
||||||
(assoc transaction-new
|
|
||||||
:amount amount
|
|
||||||
:balance balance
|
|
||||||
:token (assoc token :amount (get balance (:symbol token)))
|
|
||||||
:sign-enabled? (and to
|
|
||||||
from
|
|
||||||
(nil? amount-error)
|
|
||||||
(not (nil? amount))
|
|
||||||
(not offline?))))))
|
|
|
@ -1,247 +0,0 @@
|
||||||
(ns legacy.status-im.subs.wallet.transactions
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ethereum.transactions.core :as transactions]
|
|
||||||
[legacy.status-im.notifications.wallet :as notifications.wallet]
|
|
||||||
[legacy.status-im.wallet.db :as wallet.db]
|
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[utils.datetime :as datetime]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.money :as money]))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/accounts
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet]
|
|
||||||
(get wallet :accounts)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/account-by-transaction-hash
|
|
||||||
:<- [:wallet-legacy/accounts]
|
|
||||||
(fn [accounts [_ tx-hash]]
|
|
||||||
(some (fn [[address account]]
|
|
||||||
(when-let [transaction (get-in account [:transactions tx-hash])]
|
|
||||||
(assoc transaction :address address)))
|
|
||||||
accounts)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/transactions
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet [_ address]]
|
|
||||||
(get-in wallet [:accounts address :transactions])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/filters
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet]
|
|
||||||
(get wallet :filters)))
|
|
||||||
|
|
||||||
(defn enrich-transaction
|
|
||||||
[{:keys [type to from value token] :as transaction}
|
|
||||||
contacts native-currency]
|
|
||||||
(let [[contact-address key-contact key-wallet]
|
|
||||||
(if (= type :inbound)
|
|
||||||
[from :from-contact :to-wallet]
|
|
||||||
[to :to-contact :from-wallet])
|
|
||||||
wallet (i18n/label :t/main-wallet)
|
|
||||||
contact (get contacts contact-address)
|
|
||||||
{:keys [symbol-display decimals] :as asset}
|
|
||||||
(or token native-currency)
|
|
||||||
amount-text (if value
|
|
||||||
(wallet.utils/format-amount value decimals)
|
|
||||||
"...")
|
|
||||||
currency-text (when asset
|
|
||||||
(clojure.core/name (or symbol-display
|
|
||||||
(:symbol asset))))]
|
|
||||||
(cond-> transaction
|
|
||||||
contact (assoc key-contact (:name contact))
|
|
||||||
:always (assoc key-wallet
|
|
||||||
wallet
|
|
||||||
:amount-text amount-text
|
|
||||||
:currency-text currency-text))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.transactions/transactions
|
|
||||||
(fn [[_ address] _]
|
|
||||||
[(re-frame/subscribe [:wallet-legacy/transactions address])
|
|
||||||
(re-frame/subscribe [:contacts/contacts-by-address])
|
|
||||||
(re-frame/subscribe [:ethereum/native-currency])])
|
|
||||||
(fn [[transactions contacts native-currency]]
|
|
||||||
(reduce (fn [acc [tx-hash transaction]]
|
|
||||||
(assoc acc
|
|
||||||
tx-hash
|
|
||||||
(enrich-transaction transaction contacts native-currency))) ;;TODO this doesn't
|
|
||||||
;;look good for performance, we need to calculate this only once for each transaction
|
|
||||||
{}
|
|
||||||
transactions)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.transactions/all-filters?
|
|
||||||
:<- [:wallet-legacy/filters]
|
|
||||||
(fn [filters]
|
|
||||||
(= wallet.db/default-wallet-filters
|
|
||||||
filters)))
|
|
||||||
|
|
||||||
(def filters-labels
|
|
||||||
{:inbound (i18n/label :t/incoming)
|
|
||||||
:outbound (i18n/label :t/outgoing)
|
|
||||||
:pending (i18n/label :t/pending)
|
|
||||||
:failed (i18n/label :t/failed)})
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.transactions/filters
|
|
||||||
:<- [:wallet-legacy/filters]
|
|
||||||
(fn [filters]
|
|
||||||
(map (fn [id]
|
|
||||||
(let [checked? (filters id)]
|
|
||||||
{:id id
|
|
||||||
:label (filters-labels id)
|
|
||||||
:checked? checked?
|
|
||||||
:on-touch #(if checked?
|
|
||||||
(re-frame/dispatch [:wallet-legacy.transactions/remove-filter id])
|
|
||||||
(re-frame/dispatch [:wallet-legacy.transactions/add-filter id]))}))
|
|
||||||
wallet.db/default-wallet-filters)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.transactions.filters/screen
|
|
||||||
:<- [:wallet-legacy.transactions/filters]
|
|
||||||
:<- [:wallet-legacy.transactions/all-filters?]
|
|
||||||
(fn [[filters all-filters?]]
|
|
||||||
{:all-filters? all-filters?
|
|
||||||
:filters filters
|
|
||||||
:on-touch-select-all (when-not all-filters?
|
|
||||||
#(re-frame/dispatch
|
|
||||||
[:wallet-legacy.transactions/add-all-filters]))}))
|
|
||||||
|
|
||||||
(defn- enrich-transaction-for-list
|
|
||||||
[filters
|
|
||||||
{:keys [type from-contact from to-contact to timestamp] :as transaction}
|
|
||||||
address]
|
|
||||||
(when (filters type)
|
|
||||||
(assoc
|
|
||||||
(case type
|
|
||||||
:inbound
|
|
||||||
(assoc transaction
|
|
||||||
:label (i18n/label :t/from-capitalized)
|
|
||||||
:contact-accessibility-label :sender-text
|
|
||||||
:address-accessibility-label :sender-address-text
|
|
||||||
:contact from-contact
|
|
||||||
:address from)
|
|
||||||
(assoc transaction
|
|
||||||
:label (i18n/label :t/to-capitalized)
|
|
||||||
:contact-accessibility-label :recipient-name-text
|
|
||||||
:address-accessibility-label :recipient-address-text
|
|
||||||
:contact to-contact
|
|
||||||
:address to))
|
|
||||||
:time-formatted (datetime/timestamp->time timestamp)
|
|
||||||
:on-touch-fn #(re-frame/dispatch [:wallet-legacy.ui/show-transaction-details
|
|
||||||
(:hash transaction)
|
|
||||||
address]))))
|
|
||||||
|
|
||||||
(defn group-transactions-by-date
|
|
||||||
[transactions]
|
|
||||||
(->> transactions
|
|
||||||
(group-by #(datetime/timestamp->date-key (:timestamp %)))
|
|
||||||
(sort-by key >)
|
|
||||||
(map (fn [[date-key transactions]]
|
|
||||||
{:title (datetime/timestamp->mini-date (:timestamp (first transactions)))
|
|
||||||
:key date-key
|
|
||||||
:data (sort-by :timestamp > transactions)}))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.transactions.history/screen
|
|
||||||
(fn [[_ address] _]
|
|
||||||
[(re-frame/subscribe [:wallet-legacy.transactions/transactions address])
|
|
||||||
(re-frame/subscribe [:wallet-legacy/filters])
|
|
||||||
(re-frame/subscribe [:wallet-legacy.transactions/all-filters?])])
|
|
||||||
(fn [[transactions filters all-filters?] [_ address]]
|
|
||||||
{:all-filters? all-filters?
|
|
||||||
:total (count transactions)
|
|
||||||
:transaction-history-sections
|
|
||||||
(->> transactions
|
|
||||||
vals
|
|
||||||
(keep #(enrich-transaction-for-list filters % address))
|
|
||||||
(group-transactions-by-date))}))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/recipient-recent-txs
|
|
||||||
(fn [[_ address] _]
|
|
||||||
[(re-frame/subscribe [:wallet-legacy.transactions/transactions address])])
|
|
||||||
(fn [[transactions] _]
|
|
||||||
(->> transactions
|
|
||||||
vals
|
|
||||||
(sort-by :timestamp >)
|
|
||||||
(remove #(= (:type %) :pending))
|
|
||||||
(take 3))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.transactions.details/current-transaction
|
|
||||||
(fn [[_ _ address] _]
|
|
||||||
[(re-frame/subscribe [:wallet-legacy.transactions/transactions address])
|
|
||||||
(re-frame/subscribe [:ethereum/native-currency])
|
|
||||||
(re-frame/subscribe [:chain-id])])
|
|
||||||
(fn [[transactions native-currency chain-id] [_ tx-hash _]]
|
|
||||||
(let [{:keys [gas-used gas-price fee-cap tip-cap timestamp type]
|
|
||||||
:as transaction}
|
|
||||||
(get transactions tx-hash)
|
|
||||||
native-currency-text (name (or (:symbol-display native-currency)
|
|
||||||
(:symbol native-currency)))]
|
|
||||||
(when transaction
|
|
||||||
(merge transaction
|
|
||||||
{:gas-price-eth (if gas-price
|
|
||||||
(money/wei->str :eth
|
|
||||||
gas-price
|
|
||||||
native-currency-text)
|
|
||||||
"-")
|
|
||||||
:gas-price-gwei (if gas-price
|
|
||||||
(money/wei->str :gwei
|
|
||||||
gas-price)
|
|
||||||
"-")
|
|
||||||
:fee-cap-gwei (if fee-cap
|
|
||||||
(money/wei->str :gwei
|
|
||||||
fee-cap)
|
|
||||||
"-")
|
|
||||||
:tip-cap-gwei (if tip-cap
|
|
||||||
(money/wei->str :gwei
|
|
||||||
tip-cap)
|
|
||||||
"-")
|
|
||||||
:date (datetime/timestamp->long-date timestamp)}
|
|
||||||
(if (= type :unsigned)
|
|
||||||
{:block (i18n/label :t/not-applicable)
|
|
||||||
:cost (i18n/label :t/not-applicable)
|
|
||||||
:gas-limit (i18n/label :t/not-applicable)
|
|
||||||
:gas-used (i18n/label :t/not-applicable)
|
|
||||||
:nonce (i18n/label :t/not-applicable)
|
|
||||||
:hash (i18n/label :t/not-applicable)}
|
|
||||||
{:cost (when gas-used
|
|
||||||
(money/wei->str :eth
|
|
||||||
(money/fee-value gas-used gas-price)
|
|
||||||
native-currency-text))
|
|
||||||
:url (transactions/get-transaction-details-url
|
|
||||||
chain-id
|
|
||||||
(:hash transaction))}))))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy.transactions.details/screen
|
|
||||||
(fn [[_ tx-hash address] _]
|
|
||||||
[(re-frame/subscribe [:wallet-legacy.transactions.details/current-transaction tx-hash address])
|
|
||||||
(re-frame/subscribe [:ethereum/current-block])])
|
|
||||||
(fn [[transaction current-block]]
|
|
||||||
(let [confirmations (wallet.db/get-confirmations transaction
|
|
||||||
current-block)]
|
|
||||||
(assoc transaction
|
|
||||||
:confirmations confirmations
|
|
||||||
:confirmations-progress
|
|
||||||
(if (>= confirmations transactions/confirmations-count-threshold)
|
|
||||||
100
|
|
||||||
(* 100 (/ confirmations transactions/confirmations-count-threshold)))))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:push-notifications/wallet-transactions
|
|
||||||
:<- [:push-notifications/preferences]
|
|
||||||
(fn [pref]
|
|
||||||
(first (filter #(notifications.wallet/preference= %
|
|
||||||
{:service "wallet"
|
|
||||||
:event "transaction"
|
|
||||||
:identifier "all"})
|
|
||||||
pref))))
|
|
|
@ -1,295 +0,0 @@
|
||||||
(ns legacy.status-im.subs.wallet.wallet
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ethereum.tokens :as tokens]
|
|
||||||
[legacy.status-im.utils.currency :as currency]
|
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.config :as config]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.money :as money]))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:balance
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet [_ address]]
|
|
||||||
(get-in wallet [:accounts address :balance])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:balance-default
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
:<- [:profile/wallet-accounts]
|
|
||||||
(fn [[wallet accounts]]
|
|
||||||
(get-in wallet [:accounts (:address (wallet.utils/get-default-account accounts)) :balance])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:balances
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
:<- [:multiaccount/visible-accounts]
|
|
||||||
(fn [[wallet accounts]]
|
|
||||||
(let [accounts (map :address accounts)]
|
|
||||||
(map :balance (vals (select-keys (:accounts wallet) accounts))))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:empty-balances?
|
|
||||||
:<- [:balances]
|
|
||||||
(fn [balances]
|
|
||||||
(every?
|
|
||||||
(fn [balance]
|
|
||||||
(every?
|
|
||||||
(fn [^js asset]
|
|
||||||
(or (nil? asset) (.isZero asset)))
|
|
||||||
(vals balance)))
|
|
||||||
balances)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:price
|
|
||||||
:<- [:prices]
|
|
||||||
(fn [prices [_ fsym tsym]]
|
|
||||||
(get-in prices [fsym tsym])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:last-day
|
|
||||||
:<- [:prices]
|
|
||||||
(fn [prices [_ fsym tsym]]
|
|
||||||
(get-in prices [fsym tsym :last-day])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/settings-currency
|
|
||||||
:<- [:profile/profile]
|
|
||||||
(fn [settings]
|
|
||||||
(or (get settings :currency) :usd)))
|
|
||||||
|
|
||||||
(defn get-balance-total-value
|
|
||||||
[balance prices currency token->decimals]
|
|
||||||
(reduce-kv (fn [acc sym value]
|
|
||||||
(if-let [price (get-in prices [sym currency])]
|
|
||||||
(+ acc
|
|
||||||
(or (some-> (money/internal->formatted value sym (token->decimals sym))
|
|
||||||
^js (money/crypto->fiat price)
|
|
||||||
.toNumber)
|
|
||||||
0))
|
|
||||||
acc))
|
|
||||||
0
|
|
||||||
balance))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/token->decimals
|
|
||||||
:<- [:wallet-legacy/all-tokens]
|
|
||||||
(fn [all-tokens]
|
|
||||||
(into {} (map #(vector (:symbol %) (:decimals %)) (vals all-tokens)))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:portfolio-value
|
|
||||||
:<- [:balances]
|
|
||||||
:<- [:prices]
|
|
||||||
:<- [:wallet-legacy/currency]
|
|
||||||
:<- [:wallet-legacy/token->decimals]
|
|
||||||
(fn [[balances prices currency token->decimals]]
|
|
||||||
(if (and balances prices)
|
|
||||||
(let [currency-key (-> currency :code keyword)
|
|
||||||
balance-total-value (apply
|
|
||||||
+
|
|
||||||
(map #(get-balance-total-value % prices currency-key token->decimals)
|
|
||||||
balances))]
|
|
||||||
(if (pos? balance-total-value)
|
|
||||||
(-> balance-total-value
|
|
||||||
(money/with-precision 2)
|
|
||||||
str
|
|
||||||
(i18n/format-currency (:code currency)))
|
|
||||||
"0"))
|
|
||||||
"...")))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:account-portfolio-value
|
|
||||||
(fn [[_ address] _]
|
|
||||||
[(re-frame/subscribe [:balance address])
|
|
||||||
(re-frame/subscribe [:prices])
|
|
||||||
(re-frame/subscribe [:wallet-legacy/currency])
|
|
||||||
(re-frame/subscribe [:wallet-legacy/token->decimals])])
|
|
||||||
(fn [[balance prices currency token->decimals]]
|
|
||||||
(if (and balance prices)
|
|
||||||
(let [currency-key (-> currency :code keyword)
|
|
||||||
balance-total-value (get-balance-total-value balance prices currency-key token->decimals)]
|
|
||||||
(if (pos? balance-total-value)
|
|
||||||
(-> balance-total-value
|
|
||||||
(money/with-precision 2)
|
|
||||||
str
|
|
||||||
(i18n/format-currency (:code currency)))
|
|
||||||
"0"))
|
|
||||||
"...")))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/sorted-tokens
|
|
||||||
:<- [:wallet-legacy/all-tokens]
|
|
||||||
(fn [all-tokens]
|
|
||||||
(tokens/sorted-tokens-for all-tokens)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/grouped-chain-tokens
|
|
||||||
:<- [:wallet-legacy/sorted-tokens]
|
|
||||||
:<- [:wallet-legacy/visible-tokens-symbols]
|
|
||||||
(fn [[all-tokens visible-tokens]]
|
|
||||||
(let [vt-set (set visible-tokens)]
|
|
||||||
(group-by :custom?
|
|
||||||
(map #(assoc % :checked? (boolean (get vt-set (keyword (:symbol %))))) all-tokens)))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/fetching-tx-history?
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet [_ address]]
|
|
||||||
(get-in wallet [:fetching address :history?])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/fetching-recent-tx-history?
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet [_ address]]
|
|
||||||
(get-in wallet [:fetching address :recent?])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/tx-history-fetched?
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet [_ address]]
|
|
||||||
(get-in wallet [:fetching address :all-fetched?])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/chain-explorer-link
|
|
||||||
(fn [db [_ address]]
|
|
||||||
(let [network (:networks/current-network db)
|
|
||||||
link (get-in config/default-networks-by-id
|
|
||||||
[network :chain-explorer-link])]
|
|
||||||
(when link
|
|
||||||
(str link address)))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/error-message
|
|
||||||
:<- [:wallet-legacy]
|
|
||||||
(fn [wallet]
|
|
||||||
(or (get-in wallet [:errors :balance-update])
|
|
||||||
(get-in wallet [:errors :prices-update]))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/visible-tokens-symbols
|
|
||||||
:<- [:ethereum/chain-keyword]
|
|
||||||
:<- [:profile/profile]
|
|
||||||
(fn [[chain current-multiaccount]]
|
|
||||||
(get-in current-multiaccount [:wallet-legacy/visible-tokens chain])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/visible-assets
|
|
||||||
:<- [:current-network]
|
|
||||||
:<- [:wallet-legacy/visible-tokens-symbols]
|
|
||||||
:<- [:wallet-legacy/sorted-tokens]
|
|
||||||
(fn [[network visible-tokens-symbols all-tokens-sorted]]
|
|
||||||
(conj (filter #(contains? visible-tokens-symbols (:symbol %)) all-tokens-sorted)
|
|
||||||
(tokens/native-currency network))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/visible-assets-with-amount
|
|
||||||
(fn [[_ address] _]
|
|
||||||
[(re-frame/subscribe [:balance address])
|
|
||||||
(re-frame/subscribe [:wallet-legacy/visible-assets])])
|
|
||||||
(fn [[balance visible-assets]]
|
|
||||||
(map #(assoc % :amount (get balance (:symbol %))) visible-assets)))
|
|
||||||
|
|
||||||
(defn update-value
|
|
||||||
[prices currency]
|
|
||||||
(fn [{:keys [decimals amount] :as token}]
|
|
||||||
(let [sym (:symbol token)
|
|
||||||
currency-kw (-> currency :code keyword)
|
|
||||||
price (get-in prices [sym currency-kw])]
|
|
||||||
(assoc token
|
|
||||||
:price price
|
|
||||||
:value (when (and amount price)
|
|
||||||
(-> (money/internal->formatted amount sym decimals)
|
|
||||||
(money/crypto->fiat price)
|
|
||||||
(money/with-precision 2)
|
|
||||||
str
|
|
||||||
(i18n/format-currency (:code currency))))))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/visible-assets-with-values
|
|
||||||
(fn [[_ address] _]
|
|
||||||
[(re-frame/subscribe [:wallet-legacy/visible-assets-with-amount address])
|
|
||||||
(re-frame/subscribe [:prices])
|
|
||||||
(re-frame/subscribe [:wallet-legacy/currency])])
|
|
||||||
(fn [[assets prices currency]]
|
|
||||||
(let [{:keys [tokens nfts]} (group-by #(if (:nft? %) :nfts :tokens) assets)
|
|
||||||
tokens-with-values (map (update-value prices currency) tokens)]
|
|
||||||
{:tokens tokens-with-values
|
|
||||||
:nfts nfts})))
|
|
||||||
|
|
||||||
(defn get-asset-amount
|
|
||||||
[balances sym]
|
|
||||||
(reduce #(if-let [^js bl (get %2 sym)]
|
|
||||||
(.plus ^js (or ^js %1 ^js (money/bignumber 0)) bl)
|
|
||||||
%1)
|
|
||||||
nil
|
|
||||||
balances))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/all-visible-assets-with-amount
|
|
||||||
:<- [:balances]
|
|
||||||
:<- [:wallet-legacy/visible-assets]
|
|
||||||
(fn [[balances visible-assets]]
|
|
||||||
(map #(assoc % :amount (get-asset-amount balances (:symbol %))) visible-assets)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/all-visible-assets-with-values
|
|
||||||
:<- [:wallet-legacy/all-visible-assets-with-amount]
|
|
||||||
:<- [:prices]
|
|
||||||
:<- [:wallet-legacy/currency]
|
|
||||||
(fn [[assets prices currency]]
|
|
||||||
(let [{:keys [tokens nfts]} (group-by #(if (:nft? %) :nfts :tokens) assets)
|
|
||||||
tokens-with-values (map (update-value prices currency) tokens)]
|
|
||||||
{:tokens tokens-with-values
|
|
||||||
:nfts nfts})))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/transferrable-assets-with-amount
|
|
||||||
(fn [[_ address]]
|
|
||||||
(re-frame/subscribe [:wallet-legacy/visible-assets-with-amount address]))
|
|
||||||
(fn [all-assets]
|
|
||||||
(filter #(not (:nft? %)) all-assets)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/currency
|
|
||||||
:<- [:wallet-legacy/settings-currency]
|
|
||||||
(fn [currency-id]
|
|
||||||
(get currency/currencies currency-id (get currency/currencies :usd))))
|
|
||||||
|
|
||||||
(defn filter-recipient-favs
|
|
||||||
[search-filter {:keys [name]}]
|
|
||||||
(string/includes? (string/lower-case (str name)) search-filter))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/favourites-filtered
|
|
||||||
:<- [:wallet-legacy/favourites]
|
|
||||||
:<- [:wallet-legacy/search-recipient-filter]
|
|
||||||
(fn [[favs search-filter]]
|
|
||||||
(let [favs (vals favs)]
|
|
||||||
(if (string/blank? search-filter)
|
|
||||||
favs
|
|
||||||
(filter (partial filter-recipient-favs
|
|
||||||
(string/lower-case search-filter))
|
|
||||||
favs)))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/collectible-collection
|
|
||||||
:<- [:wallet-legacy/collectible-collections]
|
|
||||||
(fn [all-collections [_ address]]
|
|
||||||
(when address
|
|
||||||
(let [all-collections (get all-collections (string/lower-case address) [])]
|
|
||||||
(sort-by :name all-collections)))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/collectible-assets-by-collection-and-address
|
|
||||||
:<- [:wallet-legacy/collectible-assets]
|
|
||||||
(fn [all-assets [_ address collectible-slug]]
|
|
||||||
(get-in all-assets [address collectible-slug] [])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:wallet-legacy/fetching-assets-by-collectible-slug
|
|
||||||
:<- [:wallet-legacy/fetching-collection-assets]
|
|
||||||
(fn [fetching-collection-assets [_ collectible-slug]]
|
|
||||||
(get fetching-collection-assets collectible-slug false)))
|
|
|
@ -1,152 +0,0 @@
|
||||||
(ns legacy.status-im.subs.wallet.wallet-test
|
|
||||||
(:require
|
|
||||||
[cljs.test :refer [deftest is testing]]
|
|
||||||
[legacy.status-im.subs.wallet.transactions :as wallet.transactions]
|
|
||||||
[legacy.status-im.subs.wallet.wallet :as wallet]
|
|
||||||
[re-frame.db :as rf-db]
|
|
||||||
[test-helpers.unit :as h]
|
|
||||||
[utils.money :as money]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
(def money-zero (money/bignumber 0))
|
|
||||||
(def money-eth (money/bignumber 8000000000000000000))
|
|
||||||
(def money-snt (money/bignumber 756000000000000000000))
|
|
||||||
(def main-account-id "0x0Fbd")
|
|
||||||
|
|
||||||
(def accounts
|
|
||||||
[{:address "0x0Fbd"
|
|
||||||
:name "Main account"
|
|
||||||
:hidden false
|
|
||||||
:removed false}
|
|
||||||
{:address "0x5B03"
|
|
||||||
:name "Secondary account"
|
|
||||||
:hidden false
|
|
||||||
:removed false}])
|
|
||||||
|
|
||||||
(def wallet
|
|
||||||
{:accounts {main-account-id
|
|
||||||
{:balance {:ETH money-eth :SNT money-snt}
|
|
||||||
:transactions {}
|
|
||||||
:max-block 0}
|
|
||||||
"0x5B03"
|
|
||||||
{:balance {:ETH money-eth :SNT money-snt}
|
|
||||||
:transactions {}
|
|
||||||
:max-block 10}}})
|
|
||||||
|
|
||||||
(def prices
|
|
||||||
{:ETH {:USD 1282.23}
|
|
||||||
:SNT {:USD 0.0232}})
|
|
||||||
|
|
||||||
(def tokens
|
|
||||||
{"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
|
|
||||||
{:address "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
|
|
||||||
:name "Ether"
|
|
||||||
:symbol :ETH
|
|
||||||
:decimals 18
|
|
||||||
:chainId 1}
|
|
||||||
"0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
|
||||||
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
|
||||||
:name "Status Network Token"
|
|
||||||
:symbol :SNT
|
|
||||||
:decimals 18
|
|
||||||
:chainId 1}})
|
|
||||||
|
|
||||||
(h/deftest-sub :balances
|
|
||||||
[sub-name]
|
|
||||||
(swap! rf-db/app-db assoc
|
|
||||||
:profile/wallet-accounts accounts
|
|
||||||
:wallet-legacy wallet)
|
|
||||||
(is (= [{:ETH money-eth
|
|
||||||
:SNT money-snt}
|
|
||||||
{:ETH money-eth
|
|
||||||
:SNT money-snt}]
|
|
||||||
(rf/sub [sub-name]))))
|
|
||||||
|
|
||||||
(h/deftest-sub :wallet-legacy/token->decimals
|
|
||||||
[sub-name]
|
|
||||||
(swap! rf-db/app-db assoc :wallet-legacy/all-tokens tokens)
|
|
||||||
(is (= {:SNT 18 :ETH 18}
|
|
||||||
(rf/sub [sub-name]))))
|
|
||||||
|
|
||||||
(deftest get-balance-total-value-test
|
|
||||||
(is (= 697.53
|
|
||||||
(wallet/get-balance-total-value
|
|
||||||
{:ETH (money/bignumber 1000000000000000000)
|
|
||||||
:SNT (money/bignumber 100000000000000000000)
|
|
||||||
:AST (money/bignumber 10000)}
|
|
||||||
{:ETH {:USD 677.91}
|
|
||||||
:SNT {:USD 0.1562}
|
|
||||||
:AST {:USD 4}}
|
|
||||||
:USD
|
|
||||||
{:ETH 18
|
|
||||||
:SNT 18
|
|
||||||
:AST 4}))))
|
|
||||||
|
|
||||||
(h/deftest-sub :portfolio-value
|
|
||||||
[sub-name]
|
|
||||||
(testing "returns fallback value when balances and prices are not available"
|
|
||||||
(is (= "..." (rf/sub [sub-name]))))
|
|
||||||
|
|
||||||
(testing "returns zero when balance is not positive"
|
|
||||||
(let [empty-wallet {:accounts {main-account-id
|
|
||||||
{:balance {:ETH money-zero
|
|
||||||
:SNT money-zero}}}}]
|
|
||||||
(swap! rf-db/app-db assoc
|
|
||||||
:profile/wallet-accounts accounts
|
|
||||||
:prices prices
|
|
||||||
:wallet-legacy empty-wallet
|
|
||||||
:wallet-legacy/all-tokens tokens)
|
|
||||||
(is (= "0" (rf/sub [sub-name])))))
|
|
||||||
|
|
||||||
(testing "returns formatted value in the default USD currency"
|
|
||||||
(swap! rf-db/app-db assoc
|
|
||||||
:profile/wallet-accounts accounts
|
|
||||||
:prices prices
|
|
||||||
:wallet-legacy wallet
|
|
||||||
:wallet-legacy/all-tokens tokens)
|
|
||||||
(is (= "20,550.76" (rf/sub [sub-name])))))
|
|
||||||
|
|
||||||
(h/deftest-sub :account-portfolio-value
|
|
||||||
[sub-name]
|
|
||||||
(testing "returns fallback value when balances and prices are not available"
|
|
||||||
(is (= "..." (rf/sub [sub-name]))))
|
|
||||||
|
|
||||||
(testing "returns zero when balance is not positive"
|
|
||||||
(let [empty-wallet {:accounts {main-account-id
|
|
||||||
{:balance {:ETH money-zero
|
|
||||||
:SNT money-zero}}}}]
|
|
||||||
(swap! rf-db/app-db assoc
|
|
||||||
:profile/wallet-accounts accounts
|
|
||||||
:prices prices
|
|
||||||
:wallet-legacy empty-wallet
|
|
||||||
:wallet-legacy/all-tokens tokens)
|
|
||||||
(is (= "0" (rf/sub [sub-name main-account-id])))))
|
|
||||||
|
|
||||||
(testing "returns formatted value in the default USD currency"
|
|
||||||
(swap! rf-db/app-db assoc
|
|
||||||
:profile/wallet-accounts accounts
|
|
||||||
:prices prices
|
|
||||||
:wallet-legacy wallet
|
|
||||||
:wallet-legacy/all-tokens tokens)
|
|
||||||
(is (= "10,275.38" (rf/sub [sub-name main-account-id])))))
|
|
||||||
|
|
||||||
(def transactions
|
|
||||||
[{:timestamp "1505912551000"}
|
|
||||||
{:timestamp "1505764322000"}
|
|
||||||
{:timestamp "1505750000000"}])
|
|
||||||
|
|
||||||
(def grouped-transactions
|
|
||||||
'({:title "20 Sep"
|
|
||||||
:key :20170920
|
|
||||||
:data
|
|
||||||
({:timestamp "1505912551000"})}
|
|
||||||
{:title "18 Sep"
|
|
||||||
:key :20170918
|
|
||||||
:data
|
|
||||||
({:timestamp "1505764322000"}
|
|
||||||
{:timestamp "1505750000000"})}))
|
|
||||||
|
|
||||||
(deftest group-transactions-by-date
|
|
||||||
(testing "Check if transactions are sorted by date"
|
|
||||||
(is (= (wallet.transactions/group-transactions-by-date transactions)
|
|
||||||
grouped-transactions))))
|
|
|
@ -11,7 +11,6 @@
|
||||||
[legacy.status-im.ui.screens.browser.accounts :as accounts]
|
[legacy.status-im.ui.screens.browser.accounts :as accounts]
|
||||||
[legacy.status-im.ui.screens.browser.empty-tab.styles :as styles]
|
[legacy.status-im.ui.screens.browser.empty-tab.styles :as styles]
|
||||||
[legacy.status-im.ui.screens.browser.views :as browser]
|
[legacy.status-im.ui.screens.browser.views :as browser]
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as components]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
|
@ -144,7 +143,7 @@
|
||||||
:container-style styles/input-container-style
|
:container-style styles/input-container-style
|
||||||
:accessibility-label :dapp-url-input
|
:accessibility-label :dapp-url-input
|
||||||
:return-key-type :go}]
|
:return-key-type :go}]
|
||||||
[components/separator-dark]
|
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]
|
||||||
[list/flat-list
|
[list/flat-list
|
||||||
{:header [list-header (empty? bookmarks)]
|
{:header [list-header (empty? bookmarks)]
|
||||||
:data bookmarks
|
:data bookmarks
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
[legacy.status-im.ui.components.icons.icons :as icons]
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
[legacy.status-im.ui.components.list.item :as list.item]
|
||||||
[legacy.status-im.ui.components.react :as react]
|
[legacy.status-im.ui.components.react :as react]
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as components]
|
|
||||||
[legacy.status-im.utils.utils :as utils]
|
[legacy.status-im.utils.utils :as utils]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
@ -32,7 +31,7 @@
|
||||||
:subtitle (utils/get-shortened-checksum-address (:address account))
|
:subtitle (utils/get-shortened-checksum-address (:address account))
|
||||||
:accessory [icons/icon :main-icons/check {:color colors/gray}]}]
|
:accessory [icons/icon :main-icons/check {:color colors/gray}]}]
|
||||||
[react/view {:padding-vertical 8}
|
[react/view {:padding-vertical 8}
|
||||||
[components/separator]]
|
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]]
|
||||||
[list.item/list-item
|
[list.item/list-item
|
||||||
{:theme :negative
|
{:theme :negative
|
||||||
:title (i18n/label :t/revoke-access)
|
:title (i18n/label :t/revoke-access)
|
||||||
|
@ -86,7 +85,7 @@
|
||||||
(js/setTimeout
|
(js/setTimeout
|
||||||
#(browser/share-link url)
|
#(browser/share-link url)
|
||||||
200))}]
|
200))}]
|
||||||
[components/separator]])
|
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]])
|
||||||
(if connected?
|
(if connected?
|
||||||
[list.item/list-item
|
[list.item/list-item
|
||||||
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
[legacy.status-im.ui.components.plus-button :as components.plus-button]
|
[legacy.status-im.ui.components.plus-button :as components.plus-button]
|
||||||
[legacy.status-im.ui.components.react :as react]
|
[legacy.status-im.ui.components.react :as react]
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
[legacy.status-im.ui.components.topbar :as topbar]
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as components]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
|
@ -67,7 +66,7 @@
|
||||||
:on-press #(do (re-frame/dispatch [:browser.ui/clear-all-browsers-pressed])
|
:on-press #(do (re-frame/dispatch [:browser.ui/clear-all-browsers-pressed])
|
||||||
(re-frame/dispatch [:browser.ui/open-empty-tab]))}]
|
(re-frame/dispatch [:browser.ui/open-empty-tab]))}]
|
||||||
:title (i18n/label :t/tabs)}]
|
:title (i18n/label :t/tabs)}]
|
||||||
[components/separator-dark]
|
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]
|
||||||
[list/flat-list
|
[list/flat-list
|
||||||
{:data (conj browsers
|
{:data (conj browsers
|
||||||
{:empty-tab true
|
{:empty-tab true
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
[legacy.status-im.ui.screens.browser.permissions.views :as permissions.views]
|
[legacy.status-im.ui.screens.browser.permissions.views :as permissions.views]
|
||||||
[legacy.status-im.ui.screens.browser.site-blocked.views :as site-blocked.views]
|
[legacy.status-im.ui.screens.browser.site-blocked.views :as site-blocked.views]
|
||||||
[legacy.status-im.ui.screens.browser.styles :as styles]
|
[legacy.status-im.ui.screens.browser.styles :as styles]
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as components]
|
|
||||||
[legacy.status-im.utils.js-resources :as js-res]
|
[legacy.status-im.utils.js-resources :as js-res]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[react-native.permissions :as components.permissions]
|
[react-native.permissions :as components.permissions]
|
||||||
|
@ -258,7 +257,7 @@
|
||||||
url-original (browser/get-current-url current-browser)]
|
url-original (browser/get-current-url current-browser)]
|
||||||
[react/view {:style styles/browser}
|
[react/view {:style styles/browser}
|
||||||
[toolbar-content url url-original secure? url-editing? unsafe?]
|
[toolbar-content url url-original secure? url-editing? unsafe?]
|
||||||
[components/separator-dark]
|
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]
|
||||||
[react/view
|
[react/view
|
||||||
(when loading?
|
(when loading?
|
||||||
[connectivity/loading-indicator-anim window-width])]
|
[connectivity/loading-indicator-anim window-width])]
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
[legacy.status-im.ui.components.topbar :as topbar]
|
||||||
[legacy.status-im.ui.screens.chat.utils :as chat.utils]
|
[legacy.status-im.ui.screens.chat.utils :as chat.utils]
|
||||||
[legacy.status-im.ui.screens.profile.components.views :as profile.components]
|
[legacy.status-im.ui.screens.profile.components.views :as profile.components]
|
||||||
[legacy.status-im.ui.screens.wallet.send.sheets :as sheets]
|
|
||||||
[legacy.status-im.utils.utils :as utils]
|
[legacy.status-im.utils.utils :as utils]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
|
@ -292,9 +291,7 @@
|
||||||
:title (:name account)
|
:title (:name account)
|
||||||
:subtitle (utils/get-shortened-checksum-address (:address account))
|
:subtitle (utils/get-shortened-checksum-address (:address account))
|
||||||
:chevron true
|
:chevron true
|
||||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
:on-press #(js/alert "funcitonality no longer supported")}]))
|
||||||
{:content (fn [] [sheets/accounts-list :from
|
|
||||||
::ens/change-address])}])}]))
|
|
||||||
|
|
||||||
(defn- registration
|
(defn- registration
|
||||||
[checked contract address public-key]
|
[checked contract address public-key]
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
[legacy.status-im.ui.screens.reset-password.views :as reset-password.views]
|
[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.sheets :as signing-sheets]
|
||||||
[legacy.status-im.ui.screens.signing.views :as signing]
|
[legacy.status-im.ui.screens.signing.views :as signing]
|
||||||
[legacy.status-im.ui.screens.wallet.request.views :as request]
|
|
||||||
[legacy.status-im.ui.screens.wallet.signing-phrase.views :as signing-phrase]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]))
|
||||||
|
@ -131,12 +129,6 @@
|
||||||
(vector? view)
|
(vector? view)
|
||||||
view
|
view
|
||||||
|
|
||||||
(= :signing-phrase view)
|
|
||||||
[signing-phrase/signing-phrase]
|
|
||||||
|
|
||||||
(= :share-account view)
|
|
||||||
[request/share-address]
|
|
||||||
|
|
||||||
(= :share-chat-key view)
|
(= :share-chat-key view)
|
||||||
[profile.user/share-chat-key]
|
[profile.user/share-chat-key]
|
||||||
|
|
||||||
|
|
|
@ -49,19 +49,6 @@
|
||||||
[legacy.status-im.ui.screens.sync-settings.views :as sync-settings]
|
[legacy.status-im.ui.screens.sync-settings.views :as sync-settings]
|
||||||
[legacy.status-im.ui.screens.wakuv2-settings.edit-node.views :as edit-wakuv2-node]
|
[legacy.status-im.ui.screens.wakuv2-settings.edit-node.views :as edit-wakuv2-node]
|
||||||
[legacy.status-im.ui.screens.wakuv2-settings.views :as wakuv2-settings]
|
[legacy.status-im.ui.screens.wakuv2-settings.views :as wakuv2-settings]
|
||||||
[legacy.status-im.ui.screens.wallet.account-settings.views :as account-settings]
|
|
||||||
[legacy.status-im.ui.screens.wallet.account.views :as wallet.account]
|
|
||||||
[legacy.status-im.ui.screens.wallet.accounts-manage.views :as accounts-manage]
|
|
||||||
[legacy.status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
|
|
||||||
[legacy.status-im.ui.screens.wallet.add-new.views :as add-account]
|
|
||||||
[legacy.status-im.ui.screens.wallet.buy-crypto.views :as wallet.buy-crypto]
|
|
||||||
[legacy.status-im.ui.screens.wallet.collectibles.views :as wallet.collectibles]
|
|
||||||
[legacy.status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens]
|
|
||||||
[legacy.status-im.ui.screens.wallet.recipient.views :as recipient]
|
|
||||||
[legacy.status-im.ui.screens.wallet.send.views :as wallet.send]
|
|
||||||
[legacy.status-im.ui.screens.wallet.settings.views :as wallet-settings]
|
|
||||||
[legacy.status-im.ui.screens.wallet.swap.views :as wallet.swap]
|
|
||||||
[legacy.status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
|
|
||||||
[status-im.contexts.chat.group-details.view :as group-details]
|
[status-im.contexts.chat.group-details.view :as group-details]
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
|
@ -106,86 +93,11 @@
|
||||||
;;TODO custom subtitle
|
;;TODO custom subtitle
|
||||||
:component group-chat/new-group}
|
:component group-chat/new-group}
|
||||||
|
|
||||||
;;WALLET
|
|
||||||
|
|
||||||
{:name :wallet-legacy
|
|
||||||
:on-focus [:wallet-legacy/tab-opened]
|
|
||||||
;;TODO wallet redesign
|
|
||||||
;;:options {:statusBar {:backgroundColor quo.colors/neutral-5}}
|
|
||||||
:component wallet.accounts/accounts-overview-old}
|
|
||||||
{:name :wallet-account
|
|
||||||
;;TODO dynamic titleaccounts-overview
|
|
||||||
:options {:insets {:top? true}}
|
|
||||||
:component wallet.account/account}
|
|
||||||
{:name :add-new-account
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:top? true :bottom? true}}
|
|
||||||
:component add-account/add-account-view}
|
|
||||||
{:name :add-new-account-pin
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:top? true}}
|
|
||||||
:component add-account/pin}
|
|
||||||
{:name :account-settings
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:top? true}}
|
|
||||||
:component account-settings/account-settings}
|
|
||||||
{:name :wallet-transaction-details
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:top? true}}
|
|
||||||
:component wallet-transactions/transaction-details}
|
|
||||||
{:name :wallet-settings-assets
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:top? true}}
|
|
||||||
:component wallet-settings/manage-assets}
|
|
||||||
{:name :wallet-add-custom-token
|
|
||||||
:on-focus [:wallet-legacy/wallet-add-custom-token]
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/add-custom-token)}}
|
|
||||||
:insets {:top? true}}
|
|
||||||
:component custom-tokens/add-custom-token}
|
|
||||||
{:name :wallet-custom-token-details
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:top? true}}
|
|
||||||
:component custom-tokens/custom-token-details}
|
|
||||||
{:name :currency-settings
|
{:name :currency-settings
|
||||||
:options {:topBar {:title {:text (i18n/label :t/main-currency)}}
|
:options {:topBar {:title {:text (i18n/label :t/main-currency)}}
|
||||||
:insets {:top? true}}
|
:insets {:top? true}}
|
||||||
:component currency-settings/currency-settings}
|
:component currency-settings/currency-settings}
|
||||||
|
|
||||||
{:name :manage-accounts
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/wallet-manage-accounts)}}
|
|
||||||
:insets {:top? true}}
|
|
||||||
:component accounts-manage/manage}
|
|
||||||
|
|
||||||
{:name :token-swap
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:top? true}}
|
|
||||||
:component wallet.swap/swap}
|
|
||||||
|
|
||||||
{:name :token-swap-advanced-nonce
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/nonce)}}
|
|
||||||
:insets {:top? true}}
|
|
||||||
:component wallet.swap/nonce-modal}
|
|
||||||
|
|
||||||
{:name :token-swap-advanced-approve-token
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/approve-token)}}
|
|
||||||
:insets {:top? true}}
|
|
||||||
:component wallet.swap/approve-token-modal}
|
|
||||||
|
|
||||||
{:name :token-swap-advanced-transaction-fee
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/transaction-fee)}}
|
|
||||||
:insets {:top? true}}
|
|
||||||
:component wallet.swap/transaction-fee-modal}
|
|
||||||
|
|
||||||
{:name :token-swap-advanced-swap-details
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/swap-details)}}
|
|
||||||
:insets {:top? true}}
|
|
||||||
:component wallet.swap/swap-details-modal}
|
|
||||||
|
|
||||||
{:name :swap-asset-selector
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:top? true}}
|
|
||||||
:component wallet.swap/asset-selector}
|
|
||||||
|
|
||||||
;;PROFILE
|
;;PROFILE
|
||||||
|
|
||||||
{:name :my-profile
|
{:name :my-profile
|
||||||
|
@ -404,20 +316,6 @@
|
||||||
:top? true}}
|
:top? true}}
|
||||||
:component communities.invite/legacy-invite}
|
:component communities.invite/legacy-invite}
|
||||||
|
|
||||||
;[Wallet] Recipient
|
|
||||||
{:name :recipient
|
|
||||||
;;TODO accessories
|
|
||||||
:options {:insets {:bottom? true
|
|
||||||
:top? true}}
|
|
||||||
:component recipient/recipient}
|
|
||||||
|
|
||||||
;[Wallet] New favourite
|
|
||||||
{:name :new-favourite
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/new-favourite)}}
|
|
||||||
:insets {:bottom? true
|
|
||||||
:top? true}}
|
|
||||||
:component recipient/new-favourite}
|
|
||||||
|
|
||||||
;QR Scanner
|
;QR Scanner
|
||||||
{:name :qr-scanner
|
{:name :qr-scanner
|
||||||
;;TODO custom topbar
|
;;TODO custom topbar
|
||||||
|
@ -438,44 +336,6 @@
|
||||||
:top? true}}
|
:top? true}}
|
||||||
:component notifications-settings/notifications-settings}
|
:component notifications-settings/notifications-settings}
|
||||||
|
|
||||||
;[Wallet] Prepare Transaction
|
|
||||||
{:name :prepare-send-transaction
|
|
||||||
:on-dissmiss [:wallet-legacy/cancel-transaction-command]
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/send-transaction)}}
|
|
||||||
:swipeToDismiss false
|
|
||||||
:hardwareBackButton {:dismissModalOnPress false}
|
|
||||||
:insets {:bottom? true
|
|
||||||
:top? true}}
|
|
||||||
:component wallet.send/prepare-send-transaction}
|
|
||||||
|
|
||||||
;[Wallet] Request Transaction
|
|
||||||
{:name :request-transaction
|
|
||||||
:on-dissmiss [:wallet-legacy/cancel-transaction-command]
|
|
||||||
:options {:topBar {:title {:text (i18n/label :t/request-transaction)}}
|
|
||||||
:swipeToDismiss false
|
|
||||||
:hardwareBackButton {:dismissModalOnPress false}
|
|
||||||
:insets {:bottom? true
|
|
||||||
:top? true}}
|
|
||||||
:component wallet.send/request-transaction}
|
|
||||||
|
|
||||||
;[Wallet] Buy crypto
|
|
||||||
{:name :buy-crypto
|
|
||||||
:insets {:bottom? true}
|
|
||||||
:component wallet.buy-crypto/container}
|
|
||||||
|
|
||||||
;[Wallet] Buy crypto website
|
|
||||||
{:name :buy-crypto-website
|
|
||||||
;;TODO subtitle
|
|
||||||
:options {:insets {:bottom? true
|
|
||||||
:top? true}}
|
|
||||||
:component wallet.buy-crypto/website}
|
|
||||||
|
|
||||||
{:name :nft-details
|
|
||||||
;;TODO dynamic title
|
|
||||||
:options {:insets {:bottom? true
|
|
||||||
:top? true}}
|
|
||||||
:component wallet.collectibles/nft-details-modal}
|
|
||||||
|
|
||||||
;[Browser] New bookmark
|
;[Browser] New bookmark
|
||||||
{:name :new-bookmark
|
{:name :new-bookmark
|
||||||
;;TODO dynamic title
|
;;TODO dynamic title
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
(:require-macros [legacy.status-im.utils.views :as views])
|
(:require-macros [legacy.status-im.utils.views :as views])
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[legacy.status-im.ethereum.tokens :as tokens]
|
|
||||||
[legacy.status-im.react-native.resources :as resources]
|
[legacy.status-im.react-native.resources :as resources]
|
||||||
[legacy.status-im.signing.eip1559 :as eip1559]
|
[legacy.status-im.signing.eip1559 :as eip1559]
|
||||||
[legacy.status-im.ui.components.bottom-panel.views :as bottom-panel]
|
[legacy.status-im.ui.components.bottom-panel.views :as bottom-panel]
|
||||||
|
@ -15,10 +14,8 @@
|
||||||
[legacy.status-im.ui.components.react :as react]
|
[legacy.status-im.ui.components.react :as react]
|
||||||
[legacy.status-im.ui.screens.signing.sheets :as sheets]
|
[legacy.status-im.ui.screens.signing.sheets :as sheets]
|
||||||
[legacy.status-im.ui.screens.signing.styles :as styles]
|
[legacy.status-im.ui.screens.signing.styles :as styles]
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as wallet.components]
|
|
||||||
[legacy.status-im.utils.deprecated-types :as types]
|
[legacy.status-im.utils.deprecated-types :as types]
|
||||||
[legacy.status-im.utils.utils :as utils]
|
[legacy.status-im.utils.utils :as utils]
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.contexts.profile.utils :as profile.utils]
|
[status-im.contexts.profile.utils :as profile.utils]
|
||||||
|
@ -57,11 +54,7 @@
|
||||||
:style {:margin-right 8}}
|
:style {:margin-right 8}}
|
||||||
display-symbol]
|
display-symbol]
|
||||||
(if icon
|
(if icon
|
||||||
[wallet.components/token-icon
|
[react/view]
|
||||||
(assoc icon
|
|
||||||
:style {:background-color colors/gray-lighter
|
|
||||||
:border-radius 16}
|
|
||||||
:image-style {:width 24 :height 24})]
|
|
||||||
[chat-icon/custom-icon-view-list (:name token) color 32])]}]
|
[chat-icon/custom-icon-view-list (:name token) color 32])]}]
|
||||||
[separator]]))
|
[separator]]))
|
||||||
|
|
||||||
|
@ -328,7 +321,6 @@
|
||||||
[{:keys [from contact amount token cancel?] :as tx}]
|
[{:keys [from contact amount token cancel?] :as tx}]
|
||||||
(views/letsubs [fee [:signing/fee]
|
(views/letsubs [fee [:signing/fee]
|
||||||
sign [:signing/sign]
|
sign [:signing/sign]
|
||||||
chain [:current-network]
|
|
||||||
{:keys [amount-error gas-error gas-error-state insufficient-balalce?]}
|
{:keys [amount-error gas-error gas-error-state insufficient-balalce?]}
|
||||||
[:signing/amount-errors (:address from)]
|
[:signing/amount-errors (:address from)]
|
||||||
keycard-multiaccount? [:keycard-multiaccount?]
|
keycard-multiaccount? [:keycard-multiaccount?]
|
||||||
|
@ -337,8 +329,8 @@
|
||||||
mainnet? [:mainnet?]
|
mainnet? [:mainnet?]
|
||||||
prices-loading? [:prices-loading?]
|
prices-loading? [:prices-loading?]
|
||||||
management-enabled? [:wallet-legacy/transactions-management-enabled?]]
|
management-enabled? [:wallet-legacy/transactions-management-enabled?]]
|
||||||
(let [display-symbol (wallet.utils/display-symbol token)
|
(let [display-symbol nil
|
||||||
fee-display-symbol (wallet.utils/display-symbol (tokens/native-currency chain))]
|
fee-display-symbol nil]
|
||||||
[react/view (styles/sheet)
|
[react/view (styles/sheet)
|
||||||
[header sign tx display-symbol fee fee-display-symbol]
|
[header sign tx display-symbol fee fee-display-symbol]
|
||||||
[separator]
|
[separator]
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
(or owned free)
|
(or owned free)
|
||||||
(re-frame/dispatch [:stickers/install-pack id])
|
(re-frame/dispatch [:stickers/install-pack id])
|
||||||
not-enough-snt? nil
|
not-enough-snt? nil
|
||||||
:else (re-frame/dispatch [:stickers/buy-pack id]))}
|
:else (fn [] (js/alert "feature no longer supported")))}
|
||||||
[react/view (styles/price-badge (and (not (or owned free)) not-enough-snt?))
|
[react/view (styles/price-badge (and (not (or owned free)) not-enough-snt?))
|
||||||
(when (and (not free) (not owned))
|
(when (and (not free) (not owned))
|
||||||
[icons/tiny-icon :tiny-icons/tiny-snt
|
[icons/tiny-icon :tiny-icons/tiny-snt
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.account.styles
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ui.components.animation :as animation]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]))
|
|
||||||
|
|
||||||
(defn card
|
|
||||||
[window-width color]
|
|
||||||
{:width (- window-width 30)
|
|
||||||
:height 161
|
|
||||||
:background-color (if (string/blank? color)
|
|
||||||
colors/blue
|
|
||||||
color)
|
|
||||||
:shadow-offset {:width 0 :height 2}
|
|
||||||
:shadow-radius 8
|
|
||||||
:shadow-opacity 1
|
|
||||||
:shadow-color (if (colors/dark?)
|
|
||||||
"rgba(0, 0, 0, 0.75)"
|
|
||||||
"rgba(0, 9, 26, 0.12)")
|
|
||||||
:elevation 2
|
|
||||||
:border-radius 8
|
|
||||||
:justify-content :space-between})
|
|
||||||
|
|
||||||
(defn divider
|
|
||||||
[]
|
|
||||||
{:height 52
|
|
||||||
:width 1
|
|
||||||
:background-color colors/black-transparent-20
|
|
||||||
:shadow-offset {:width 0 :height 2}
|
|
||||||
:shadow-radius 8
|
|
||||||
:shadow-opacity 1
|
|
||||||
:shadow-color (if (colors/dark?)
|
|
||||||
"rgba(0, 0, 0, 0.75)"
|
|
||||||
"rgba(0, 9, 26, 0.12)")})
|
|
||||||
|
|
||||||
(defn bottom-send-recv-buttons-raise
|
|
||||||
[anim-y]
|
|
||||||
(animation/timing
|
|
||||||
anim-y
|
|
||||||
{:toValue 0
|
|
||||||
:duration 200
|
|
||||||
:easing (.-ease ^js animation/easing)
|
|
||||||
:useNativeDriver true}))
|
|
||||||
|
|
||||||
(defn bottom-send-recv-buttons-lower
|
|
||||||
[anim-y y]
|
|
||||||
(animation/timing
|
|
||||||
anim-y
|
|
||||||
{:toValue y
|
|
||||||
:duration 200
|
|
||||||
:easing (.-ease ^js animation/easing)
|
|
||||||
:useNativeDriver true}))
|
|
||||||
|
|
||||||
(def round-action-button
|
|
||||||
{:background-color colors/blue
|
|
||||||
:height 44
|
|
||||||
:flex 1
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:width 44
|
|
||||||
:border-radius 44})
|
|
||||||
|
|
||||||
(def top-actions
|
|
||||||
{:flex 1
|
|
||||||
:flex-direction :row
|
|
||||||
:justify-content :space-between
|
|
||||||
:width "60%"
|
|
||||||
:align-self :center})
|
|
|
@ -1,363 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.account.views
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.animation :as animation]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.core :as components.core]
|
|
||||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.components.spacing :as spacing]
|
|
||||||
[legacy.status-im.ui.components.tabs :as tabs]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[legacy.status-im.ui.screens.wallet.account.styles :as styles]
|
|
||||||
[legacy.status-im.ui.screens.wallet.accounts.common :as common]
|
|
||||||
[legacy.status-im.ui.screens.wallet.accounts.sheets :as sheets]
|
|
||||||
[legacy.status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto]
|
|
||||||
[legacy.status-im.ui.screens.wallet.collectibles.views :as collectibles.views]
|
|
||||||
[legacy.status-im.ui.screens.wallet.transactions.views :as history]
|
|
||||||
[quo.core :as quo]
|
|
||||||
[quo.foundations.colors :as quo.colors]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.config :as config]
|
|
||||||
[utils.address :as address]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf])
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
|
||||||
|
|
||||||
(def state (reagent/atom {:tab :assets}))
|
|
||||||
(def selected-tab (reagent/atom :tokens))
|
|
||||||
|
|
||||||
(defn button
|
|
||||||
[label icon color handler]
|
|
||||||
[react/touchable-highlight {:on-press handler :style {:flex 1}}
|
|
||||||
[react/view {:flex 1 :align-items :center :justify-content :center}
|
|
||||||
[react/view {:flex-direction :row :align-items :center}
|
|
||||||
[icons/icon icon {:color color}]
|
|
||||||
[react/text {:style {:margin-left 8 :color color}} label]]]])
|
|
||||||
|
|
||||||
(def button-group-height 52)
|
|
||||||
|
|
||||||
(views/defview account-card
|
|
||||||
[{:keys [address color type] :as account}]
|
|
||||||
(views/letsubs [currency [:wallet-legacy/currency]
|
|
||||||
portfolio-value [:account-portfolio-value address]
|
|
||||||
window-width [:dimensions/window-width]
|
|
||||||
prices-loading? [:prices-loading?]]
|
|
||||||
[react/view {:style (styles/card window-width color)}
|
|
||||||
[react/view {:padding 16 :padding-bottom 12 :flex 1 :justify-content :space-between}
|
|
||||||
[react/view {:style {:flex-direction :row}}
|
|
||||||
(if prices-loading?
|
|
||||||
[react/small-loading-indicator :colors/white-persist]
|
|
||||||
[react/text {:style {:font-size 32 :color colors/white-persist :font-weight "600"}}
|
|
||||||
portfolio-value])
|
|
||||||
[react/text {:style {:font-size 32 :color colors/white-transparent-persist :font-weight "600"}}
|
|
||||||
(str " " (:code currency))]]
|
|
||||||
[components.core/text
|
|
||||||
{:number-of-lines 1
|
|
||||||
:ellipsize-mode :middle
|
|
||||||
:monospace true
|
|
||||||
:size :small
|
|
||||||
:style {:width (/ window-width 3)
|
|
||||||
:line-height 22
|
|
||||||
:color colors/white-transparent-70-persist}}
|
|
||||||
(address/normalized-hex address)]]
|
|
||||||
[react/view {:position :absolute :top 12 :right 12}
|
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet-legacy/share-popover address])}
|
|
||||||
[icons/icon :main-icons/share
|
|
||||||
{:color colors/white-persist
|
|
||||||
:accessibility-label :share-wallet-address-icon}]]]
|
|
||||||
[react/view
|
|
||||||
{:height button-group-height
|
|
||||||
:background-color colors/black-transparent-20
|
|
||||||
:border-bottom-right-radius 8
|
|
||||||
:border-bottom-left-radius 8
|
|
||||||
:flex-direction :row}
|
|
||||||
(if (= type :watch)
|
|
||||||
[react/view {:flex 1 :align-items :center :justify-content :center}
|
|
||||||
[react/text {:style {:margin-left 8 :color colors/white-persist}}
|
|
||||||
(i18n/label :t/watch-only)]]
|
|
||||||
[button
|
|
||||||
(i18n/label :t/wallet-send)
|
|
||||||
:main-icons/send
|
|
||||||
colors/white-persist
|
|
||||||
#(re-frame/dispatch [:wallet-legacy/prepare-transaction-from-wallet account])])
|
|
||||||
[react/view {:style (styles/divider)}]
|
|
||||||
[button
|
|
||||||
(i18n/label :t/receive)
|
|
||||||
:main-icons/receive
|
|
||||||
colors/white-persist
|
|
||||||
#(re-frame/dispatch [:wallet-legacy/share-popover address])]]]))
|
|
||||||
|
|
||||||
(views/defview transactions
|
|
||||||
[address]
|
|
||||||
(views/letsubs [data [:wallet-legacy.transactions.history/screen address]]
|
|
||||||
[history/history-list data address]))
|
|
||||||
|
|
||||||
(defn opensea-link
|
|
||||||
[address]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch [:browser.ui/open-url (str "https://opensea.io/" address)])}
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:padding-horizontal 14
|
|
||||||
:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:background-color colors/blue-light
|
|
||||||
:height 52}}
|
|
||||||
[icons/tiny-icon
|
|
||||||
:tiny-icons/tiny-external
|
|
||||||
{:color colors/blue
|
|
||||||
:container-style {:margin-right 5}}]
|
|
||||||
[react/text
|
|
||||||
{:style {:color colors/blue}}
|
|
||||||
(i18n/label :t/check-on-opensea)]]])
|
|
||||||
|
|
||||||
(views/defview assets-and-collections-new
|
|
||||||
[address]
|
|
||||||
(views/letsubs [{:keys [tokens]} [:wallet-legacy/visible-assets-with-values address]
|
|
||||||
currency [:wallet-legacy/currency]
|
|
||||||
opensea-enabled? [:opensea-enabled?]
|
|
||||||
collectible-collection [:wallet-legacy/collectible-collection address]]
|
|
||||||
;ethereum-network? [:ethereum-network?]]
|
|
||||||
(let [tab @selected-tab]
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[react/view {:padding-horizontal 20 :padding-bottom 20}
|
|
||||||
[quo/tabs
|
|
||||||
{:size 24
|
|
||||||
:on-change #(reset! selected-tab %)
|
|
||||||
:default-active :tokens
|
|
||||||
:data [{:id :tokens :label "Tokens"}
|
|
||||||
{:id :nft :label "NFTs"}
|
|
||||||
{:id :activity :label "Activity"}]}]]
|
|
||||||
(cond
|
|
||||||
(= tab :tokens)
|
|
||||||
[react/scroll-view
|
|
||||||
(for [item tokens]
|
|
||||||
^{:key (:name item)}
|
|
||||||
[common/render-asset-new item nil nil (:code currency)])]
|
|
||||||
(= tab :nft)
|
|
||||||
[:<>
|
|
||||||
[opensea-link address]
|
|
||||||
;; Hide collectibles behind a feature flag
|
|
||||||
(when config/collectibles-enabled?
|
|
||||||
(cond
|
|
||||||
(not opensea-enabled?)
|
|
||||||
[collectibles.views/enable-opensea-view]
|
|
||||||
|
|
||||||
(and opensea-enabled? (seq collectible-collection))
|
|
||||||
[collectibles.views/nft-collections address]
|
|
||||||
|
|
||||||
:else
|
|
||||||
[react/view {:align-items :center :margin-top 32}
|
|
||||||
[react/text {:style {:color colors/gray}}
|
|
||||||
(i18n/label :t/no-collectibles)]]))]
|
|
||||||
(= tab :activity)
|
|
||||||
[transactions address])])))
|
|
||||||
|
|
||||||
(views/defview bottom-send-recv-buttons
|
|
||||||
[{:keys [address type] :as account} anim-y]
|
|
||||||
[react/animated-view
|
|
||||||
{:style {:background-color colors/white
|
|
||||||
:bottom 0
|
|
||||||
:flex-direction :row
|
|
||||||
:height button-group-height
|
|
||||||
:position :absolute
|
|
||||||
:shadow-offset {:width 0 :height 1}
|
|
||||||
:shadow-opacity 0.75
|
|
||||||
:shadow-radius 1
|
|
||||||
:transform [{:translateY anim-y}]
|
|
||||||
:width "100%"}}
|
|
||||||
(if (= type :watch)
|
|
||||||
[react/view {:flex 1 :align-items :center :justify-content :center}
|
|
||||||
[react/text {:style {:margin-left 8 :color colors/blue-persist}}
|
|
||||||
(i18n/label :t/watch-only)]]
|
|
||||||
[button
|
|
||||||
(i18n/label :t/wallet-send)
|
|
||||||
:main-icons/send
|
|
||||||
colors/blue-persist
|
|
||||||
#(re-frame/dispatch [:wallet-legacy/prepare-transaction-from-wallet account])])
|
|
||||||
[button
|
|
||||||
(i18n/label :t/receive)
|
|
||||||
:main-icons/receive
|
|
||||||
colors/blue-persist
|
|
||||||
#(re-frame/dispatch [:wallet-legacy/share-popover address])]])
|
|
||||||
|
|
||||||
(defn anim-listener
|
|
||||||
[anim-y scroll-y]
|
|
||||||
(let [to-show (atom false)]
|
|
||||||
(animation/add-listener
|
|
||||||
scroll-y
|
|
||||||
(fn [anim]
|
|
||||||
(let [y-trigger 149]
|
|
||||||
(cond
|
|
||||||
(and (>= (.-value anim) y-trigger) (not @to-show))
|
|
||||||
(animation/start
|
|
||||||
(styles/bottom-send-recv-buttons-raise anim-y)
|
|
||||||
#(reset! to-show true))
|
|
||||||
|
|
||||||
(and (< (.-value anim) y-trigger) @to-show)
|
|
||||||
(animation/start
|
|
||||||
(styles/bottom-send-recv-buttons-lower anim-y button-group-height)
|
|
||||||
#(reset! to-show false))))))))
|
|
||||||
|
|
||||||
(defn round-action-button
|
|
||||||
[{:keys [icon title on-press]}]
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:align-items :center
|
|
||||||
:margin-vertical (:large spacing/spacing)}}
|
|
||||||
[react/touchable-opacity
|
|
||||||
{:style styles/round-action-button
|
|
||||||
:on-press on-press}
|
|
||||||
(icons/icon icon {:color colors/white})]
|
|
||||||
[components.core/text
|
|
||||||
{:color :secondary
|
|
||||||
:size :small
|
|
||||||
:style {:margin-top (:tiny spacing/spacing)}}
|
|
||||||
title]])
|
|
||||||
|
|
||||||
(defn top-actions
|
|
||||||
[]
|
|
||||||
[react/view {:style styles/top-actions}
|
|
||||||
[round-action-button
|
|
||||||
{:icon :main-icons/add
|
|
||||||
:title (i18n/label :t/buy-crypto)
|
|
||||||
:on-press #(re-frame/dispatch [:buy-crypto.ui/open-screen])}]
|
|
||||||
[round-action-button
|
|
||||||
{:icon :main-icons/change
|
|
||||||
:title (i18n/label :t/swap)
|
|
||||||
:on-press #(re-frame/dispatch [:open-modal :token-swap])}]])
|
|
||||||
|
|
||||||
(views/defview assets-and-collections
|
|
||||||
[address]
|
|
||||||
(views/letsubs [{:keys [tokens]} [:wallet-legacy/visible-assets-with-values address]
|
|
||||||
currency [:wallet-legacy/currency]
|
|
||||||
opensea-enabled? [:opensea-enabled?]
|
|
||||||
collectible-collection [:wallet-legacy/collectible-collection address]
|
|
||||||
ethereum-network? [:ethereum-network?]]
|
|
||||||
(let [{:keys [tab]} @state]
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[react/view {:flex-direction :row :margin-bottom 8 :padding-horizontal 4}
|
|
||||||
[tabs/tab-title state :assets (i18n/label :t/wallet-assets) (= tab :assets)]
|
|
||||||
(when ethereum-network?
|
|
||||||
[tabs/tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)])
|
|
||||||
[tabs/tab-title state :history (i18n/label :t/history) (= tab :history)]]
|
|
||||||
[quo/separator {:style {:margin-top -8}}]
|
|
||||||
(cond
|
|
||||||
(= tab :assets)
|
|
||||||
[:<>
|
|
||||||
(for [item tokens]
|
|
||||||
^{:key (:name item)}
|
|
||||||
[common/render-asset item nil nil (:code currency)])]
|
|
||||||
(= tab :nft)
|
|
||||||
[:<>
|
|
||||||
[opensea-link address]
|
|
||||||
;; Hide collectibles behind a feature flag
|
|
||||||
(when config/collectibles-enabled?
|
|
||||||
(cond
|
|
||||||
(not opensea-enabled?)
|
|
||||||
[collectibles.views/enable-opensea-view]
|
|
||||||
|
|
||||||
(and opensea-enabled? (seq collectible-collection))
|
|
||||||
[collectibles.views/nft-collections address]
|
|
||||||
|
|
||||||
:else
|
|
||||||
[react/view {:align-items :center :margin-top 32}
|
|
||||||
[react/text {:style {:color colors/gray}}
|
|
||||||
(i18n/label :t/no-collectibles)]]))]
|
|
||||||
(= tab :history)
|
|
||||||
[transactions address])])))
|
|
||||||
|
|
||||||
(defn account-new
|
|
||||||
[selected-account]
|
|
||||||
(let [;{:keys [name address] :as account} (rf/sub [:account-by-address selected-account])
|
|
||||||
currency (rf/sub [:wallet-legacy/currency])
|
|
||||||
portfolio-value (rf/sub [:account-portfolio-value selected-account])
|
|
||||||
width (rf/sub [:dimensions/window-width])
|
|
||||||
button-width (/ (- width 40 (* 2 12)) 3)]
|
|
||||||
;fetching-error (rf/sub [:wallet-legacy/fetching-error])]
|
|
||||||
[react/view
|
|
||||||
{:flex 1
|
|
||||||
:background-color (quo.colors/theme-colors quo.colors/white quo.colors/neutral-90)
|
|
||||||
:border-top-left-radius 20
|
|
||||||
:border-top-right-radius 20
|
|
||||||
:elevation 4
|
|
||||||
:shadow-opacity 1
|
|
||||||
:shadow-radius 20
|
|
||||||
:shadow-color (:shadow-01 @colors/theme)
|
|
||||||
:shadow-offset {:width 0 :height 4}}
|
|
||||||
[react/view {:padding 20}
|
|
||||||
[quo/text {:size :heading-2 :weight :semi-bold} (str portfolio-value " " (:code currency))]]
|
|
||||||
[react/view
|
|
||||||
[react/scroll-view {:horizontal true :margin-bottom 32 :showsHorizontalScrollIndicator false}
|
|
||||||
[react/view {:width 20}]
|
|
||||||
[quo/button {:size 56 :width button-width :above :i/placeholder} "Buy"]
|
|
||||||
[react/view {:width 12}]
|
|
||||||
[quo/button {:size 56 :width button-width :type :secondary :above :i/placeholder} "Send"]
|
|
||||||
[react/view {:width 12}]
|
|
||||||
[quo/button {:size 56 :width button-width :type :secondary :above :i/placeholder}
|
|
||||||
"Receive"]
|
|
||||||
[react/view {:width 12}]
|
|
||||||
[quo/button {:size 56 :width button-width :type :secondary :above :i/placeholder} "Swap"]
|
|
||||||
[react/view {:width 20}]]]
|
|
||||||
[assets-and-collections-new selected-account]]))
|
|
||||||
|
|
||||||
(views/defview account
|
|
||||||
[]
|
|
||||||
(views/letsubs [{:keys [name address] :as current-account} [:multiaccount/current-account]
|
|
||||||
fetching-error [:wallet-legacy/fetching-error]]
|
|
||||||
(let [anim-y (animation/create-value button-group-height)
|
|
||||||
scroll-y (animation/create-value 0)]
|
|
||||||
(anim-listener anim-y scroll-y)
|
|
||||||
[:<>
|
|
||||||
[topbar/topbar
|
|
||||||
{:title name
|
|
||||||
:right-accessories
|
|
||||||
[{:icon :main-icons/more
|
|
||||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content sheets/account-settings
|
|
||||||
:content-height 60}])}]}]
|
|
||||||
[react/animated-scroll-view
|
|
||||||
{:contentContainerStyle {:padding-bottom button-group-height}
|
|
||||||
:on-scroll (animation/event
|
|
||||||
[{:nativeEvent {:contentOffset {:y scroll-y}}}]
|
|
||||||
{:useNativeDriver true})
|
|
||||||
:scrollEventThrottle 1
|
|
||||||
:refreshControl (common/refresh-control
|
|
||||||
(and
|
|
||||||
@common/updates-counter
|
|
||||||
@(re-frame/subscribe [:wallet-legacy/refreshing-history?])))}
|
|
||||||
(when fetching-error
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:align-items :center
|
|
||||||
:margin 8}}
|
|
||||||
[icons/icon
|
|
||||||
:main-icons/warning
|
|
||||||
{:color :red
|
|
||||||
:container-style {:background-color (colors/get-color :negative-02)
|
|
||||||
:height 40
|
|
||||||
:width 40
|
|
||||||
:border-radius 20
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center}}]
|
|
||||||
[react/view
|
|
||||||
{:style {:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:margin-top 8
|
|
||||||
:margin-horizontal 67.5
|
|
||||||
:text-align :center}}
|
|
||||||
[components.core/text
|
|
||||||
{:color :secondary
|
|
||||||
:size :small
|
|
||||||
:style {:text-align :center}}
|
|
||||||
(i18n/label :t/transfers-fetching-failure)]]])
|
|
||||||
[react/view {:padding-left 16}
|
|
||||||
[react/scroll-view {:horizontal true}
|
|
||||||
[react/view {:flex-direction :row :padding-top 8 :padding-bottom 12}
|
|
||||||
[account-card current-account]]]]
|
|
||||||
(if config/swap-enabled?
|
|
||||||
[top-actions]
|
|
||||||
[buy-crypto/banner])
|
|
||||||
[assets-and-collections address]]
|
|
||||||
[bottom-send-recv-buttons current-account anim-y]])))
|
|
|
@ -1,177 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.account-settings.views
|
|
||||||
(:require-macros [legacy.status-im.utils.views :refer [defview letsubs]])
|
|
||||||
(:require
|
|
||||||
[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.components.toolbar :as toolbar]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.security.core :as security]))
|
|
||||||
|
|
||||||
(defn not-valid-password?
|
|
||||||
[password]
|
|
||||||
(< (count (security/safe-unmask-data password)) 6))
|
|
||||||
|
|
||||||
(defn delete-account
|
|
||||||
[_]
|
|
||||||
(let [password (reagent/atom nil)
|
|
||||||
text-input-ref (atom nil)
|
|
||||||
error (reagent/atom nil)]
|
|
||||||
(fn [account]
|
|
||||||
(when (and @text-input-ref error (not @password))
|
|
||||||
(.clear ^js @text-input-ref))
|
|
||||||
[react/view {:padding 20 :width 300}
|
|
||||||
[quo/text-input
|
|
||||||
{:style {:margin-bottom 40}
|
|
||||||
:label (i18n/label :t/password)
|
|
||||||
: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 %))
|
|
||||||
:get-ref #(reset! text-input-ref %)
|
|
||||||
:error (when (and @error (not @password))
|
|
||||||
(if (= :wrong-password @error)
|
|
||||||
(i18n/label :t/wrong-password)
|
|
||||||
(str @error)))}]
|
|
||||||
[quo/button
|
|
||||||
{:on-press (fn []
|
|
||||||
(re-frame/dispatch [:wallet-legacy.accounts/delete-key
|
|
||||||
account
|
|
||||||
@password
|
|
||||||
#(reset! error :wrong-password)])
|
|
||||||
(reset! password nil))
|
|
||||||
:theme :negative
|
|
||||||
:accessibility-label :delete-account-confirm
|
|
||||||
:disabled (not-valid-password? @password)}
|
|
||||||
(i18n/label :t/delete)]])))
|
|
||||||
|
|
||||||
(defview colors-popover
|
|
||||||
[selected-color on-press]
|
|
||||||
(letsubs [width [:dimensions/window-width]]
|
|
||||||
[react/view {:flex 1 :padding-bottom 16}
|
|
||||||
[react/scroll-view {:style {:margin 16}}
|
|
||||||
(doall
|
|
||||||
(for [color colors/account-colors]
|
|
||||||
^{:key color}
|
|
||||||
[react/touchable-highlight {:on-press #(on-press color)}
|
|
||||||
[react/view
|
|
||||||
{:height 52
|
|
||||||
:background-color color
|
|
||||||
:border-radius 8
|
|
||||||
:width (* 0.7 width)
|
|
||||||
:justify-content :center
|
|
||||||
:padding-left 12
|
|
||||||
:margin-bottom 16}
|
|
||||||
[react/view
|
|
||||||
{:height 32
|
|
||||||
:width 32
|
|
||||||
:border-radius 20
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center
|
|
||||||
:background-color colors/black-transparent}
|
|
||||||
(when (= selected-color color)
|
|
||||||
[icons/icon :main-icons/check {:color colors/white}])]]]))]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:center
|
|
||||||
[quo/button
|
|
||||||
{:on-press #(re-frame/dispatch [:hide-popover])
|
|
||||||
:type :secondary}
|
|
||||||
(i18n/label :t/cancel)]}]]))
|
|
||||||
|
|
||||||
(defn property
|
|
||||||
[label value]
|
|
||||||
[react/view {:margin-top 28}
|
|
||||||
[react/text {:style {:color colors/gray}} label]
|
|
||||||
(if (string? value)
|
|
||||||
[react/text {:style {:margin-top 6}} value]
|
|
||||||
value)])
|
|
||||||
|
|
||||||
(defview account-settings
|
|
||||||
[]
|
|
||||||
(letsubs [{:keys [address color path type] :as account} [:multiaccount/current-account]
|
|
||||||
new-account (reagent/atom nil)
|
|
||||||
keycard? [:keycard-multiaccount?]]
|
|
||||||
[react/keyboard-avoiding-view
|
|
||||||
{:style {:flex 1}
|
|
||||||
:ignore-offset true}
|
|
||||||
[topbar/topbar
|
|
||||||
(cond-> {:title (i18n/label :t/account-settings)}
|
|
||||||
(and @new-account (not= "" (:name @new-account)))
|
|
||||||
(assoc :right-accessories
|
|
||||||
[{:label (i18n/label :t/apply)
|
|
||||||
:on-press
|
|
||||||
#(do
|
|
||||||
(re-frame/dispatch [:wallet-legacy.accounts/save-account
|
|
||||||
account
|
|
||||||
@new-account])
|
|
||||||
(reset! new-account nil))}]))]
|
|
||||||
[react/scroll-view
|
|
||||||
{:keyboard-should-persist-taps :handled
|
|
||||||
:style {:flex 1}}
|
|
||||||
[react/view {:padding-bottom 28 :padding-top 10}
|
|
||||||
[react/view {:margin-horizontal 16}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/account-name)
|
|
||||||
:auto-focus false
|
|
||||||
:default-value (:name account)
|
|
||||||
:accessibility-label :enter-account-name
|
|
||||||
:on-change-text #(swap! new-account assoc :name %)}]
|
|
||||||
[react/text {:style {:margin-top 16 :color colors/gray}} (i18n/label :t/account-color)]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch [:show-popover
|
|
||||||
{:view [colors-popover color
|
|
||||||
(fn [new-color]
|
|
||||||
(swap! new-account assoc :color new-color)
|
|
||||||
(re-frame/dispatch [:hide-popover]))]
|
|
||||||
:style {:max-height "60%"}}])}
|
|
||||||
[react/view
|
|
||||||
{:height 52
|
|
||||||
:margin-top 12
|
|
||||||
:background-color (or (:color @new-account) color)
|
|
||||||
:border-radius 8
|
|
||||||
:align-items :flex-end
|
|
||||||
:justify-content :center
|
|
||||||
:padding-right 12}
|
|
||||||
[icons/icon :main-icons/dropdown {:color colors/white}]]]
|
|
||||||
[property (i18n/label :t/type)
|
|
||||||
(case type
|
|
||||||
:watch (i18n/label :t/watch-only)
|
|
||||||
(:key :seed) (i18n/label :t/off-status-tree)
|
|
||||||
(i18n/label :t/on-status-tree))]
|
|
||||||
[property (i18n/label :t/wallet-address)
|
|
||||||
[copyable-text/copyable-text-view
|
|
||||||
{:copied-text address}
|
|
||||||
[quo/text
|
|
||||||
{:style {:margin-top 6}
|
|
||||||
:monospace true}
|
|
||||||
address]]]
|
|
||||||
(when-not (= type :watch)
|
|
||||||
[property (i18n/label :t/derivation-path)
|
|
||||||
[copyable-text/copyable-text-view
|
|
||||||
{:copied-text path}
|
|
||||||
[quo/text
|
|
||||||
{:style {:margin-top 6}
|
|
||||||
:monospace true} path]]])
|
|
||||||
(when-not (= type :watch)
|
|
||||||
[property (i18n/label :t/storage)
|
|
||||||
(i18n/label (if keycard?
|
|
||||||
:t/keycard
|
|
||||||
:t/this-device))])]
|
|
||||||
(when (#{:key :seed :watch} type)
|
|
||||||
[react/view
|
|
||||||
[react/view {:margin-bottom 8 :margin-top 28 :height 1 :background-color colors/gray-lighter}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :negative
|
|
||||||
:title (i18n/label :t/delete-account)
|
|
||||||
:on-press #(if (= :watch type)
|
|
||||||
(re-frame/dispatch [:wallet-legacy.settings/show-delete-account-confirmation
|
|
||||||
account])
|
|
||||||
(re-frame/dispatch [:show-popover {:view [delete-account account]}]))}]])]]]))
|
|
|
@ -1,81 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.accounts.common
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon]
|
|
||||||
[legacy.status-im.ui.components.core :as components]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as wallet.components]
|
|
||||||
[legacy.status-im.utils.utils :as utils.utils]
|
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[quo.core :as quo]
|
|
||||||
[quo.foundations.colors :as quo.colors]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[react-native.core :as rn]
|
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
;; Note(rasom): sometimes `refreshing` might get stuck on iOS if action happened
|
|
||||||
;; too fast. By updating this atom in 1s we ensure that `refreshing?` property
|
|
||||||
;; is updated properly in this case.
|
|
||||||
(def updates-counter (reagent/atom 0))
|
|
||||||
|
|
||||||
(defn schedule-counter-reset
|
|
||||||
[]
|
|
||||||
(utils.utils/set-timeout
|
|
||||||
(fn []
|
|
||||||
(swap! updates-counter inc)
|
|
||||||
(when @(re-frame/subscribe [:wallet-legacy/refreshing-history?])
|
|
||||||
(schedule-counter-reset)))
|
|
||||||
1000))
|
|
||||||
|
|
||||||
(defn refresh-action
|
|
||||||
[]
|
|
||||||
(schedule-counter-reset)
|
|
||||||
(re-frame/dispatch [:wallet-legacy.ui/pull-to-refresh-history]))
|
|
||||||
|
|
||||||
(defn refresh-control
|
|
||||||
[refreshing?]
|
|
||||||
(reagent/as-element
|
|
||||||
[rn/refresh-control
|
|
||||||
{:refreshing (boolean refreshing?)
|
|
||||||
:onRefresh refresh-action}]))
|
|
||||||
|
|
||||||
(defn render-asset
|
|
||||||
[{:keys [icon decimals amount color value] :as token} _ _ currency]
|
|
||||||
[list.item/list-item
|
|
||||||
{:title [components/text {:weight :medium}
|
|
||||||
[components/text {:weight :inherit}
|
|
||||||
(str (if amount
|
|
||||||
(wallet.utils/format-amount amount decimals)
|
|
||||||
"...")
|
|
||||||
" ")]
|
|
||||||
[components/text
|
|
||||||
{:color :secondary
|
|
||||||
:weight :inherit}
|
|
||||||
(wallet.utils/display-symbol token)]]
|
|
||||||
:subtitle (str (if value value "...") " " currency)
|
|
||||||
:accessibility-label (str (:symbol token) "-asset-value")
|
|
||||||
:icon (if icon
|
|
||||||
[wallet.components/token-icon icon]
|
|
||||||
[chat-icon/custom-icon-view-list (:name token) color])}])
|
|
||||||
|
|
||||||
(defn render-asset-new
|
|
||||||
[{:keys [icon decimals amount color value name] :as token} _ _ currency]
|
|
||||||
[rn/view {:height 56 :margin-horizontal 8 :margin-top 4}
|
|
||||||
[rn/view {:position :absolute :left 12 :top 12}
|
|
||||||
(if icon
|
|
||||||
[wallet.components/token-icon (merge icon {:width 32 :height 32})]
|
|
||||||
[chat-icon/custom-icon-view-list (:name token) color])]
|
|
||||||
[rn/view {:position :absolute :left 52 :top 8 :right 12}
|
|
||||||
[rn/view {:flex-direction :row :justify-content :space-between :align-items :center}
|
|
||||||
[quo/text {:weight :semi-bold :style {:height 22}}
|
|
||||||
name]
|
|
||||||
[quo/text {:size :paragraph-2 :weight :medium}
|
|
||||||
(str (if value value "...") " " currency)]]
|
|
||||||
[quo/text
|
|
||||||
{:size :paragraph-2
|
|
||||||
:weight :medium
|
|
||||||
:style {:color (quo.colors/theme-colors quo.colors/neutral-50 quo.colors/neutral-40)}}
|
|
||||||
(str (if amount
|
|
||||||
(wallet.utils/format-amount amount decimals)
|
|
||||||
"...")
|
|
||||||
" "
|
|
||||||
(wallet.utils/display-symbol token))]]])
|
|
|
@ -1,135 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.accounts.sheets
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[utils.i18n :as i18n]))
|
|
||||||
|
|
||||||
(defn hide-sheet-and-dispatch
|
|
||||||
[event]
|
|
||||||
(re-frame/dispatch [:bottom-sheet/hide-old])
|
|
||||||
(re-frame/dispatch event))
|
|
||||||
|
|
||||||
(defn accounts-options
|
|
||||||
[mnemonic]
|
|
||||||
(fn []
|
|
||||||
[:<>
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/wallet-manage-accounts)
|
|
||||||
:icon :main-icons/account
|
|
||||||
:accessibility-label :wallet-manage-accounts
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:navigate-to :manage-accounts])}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/wallet-manage-assets)
|
|
||||||
:icon :main-icons/token
|
|
||||||
:accessibility-label :wallet-manage-assets
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:navigate-to :wallet-settings-assets])}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/scan-tokens)
|
|
||||||
:icon :main-icons/refresh
|
|
||||||
:accessibility-label :wallet-scan-token
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy/update-balances nil true])}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/set-currency)
|
|
||||||
:icon :main-icons/language
|
|
||||||
:accessibility-label :wallet-set-currency
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:navigate-to :currency-settings])}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/view-signing)
|
|
||||||
:icon :main-icons/info
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:show-popover {:view :signing-phrase}])}]
|
|
||||||
(when mnemonic
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :negative
|
|
||||||
:title (i18n/label :t/wallet-backup-recovery-title)
|
|
||||||
:icon :main-icons/security
|
|
||||||
:accessibility-label :wallet-backup-recovery-title
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:navigate-to :backup-seed])}])]))
|
|
||||||
|
|
||||||
(defn account-card-actions
|
|
||||||
[account type wallet]
|
|
||||||
[react/view
|
|
||||||
(when-not (= type :watch)
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/wallet-send)
|
|
||||||
:icon :main-icons/send
|
|
||||||
:accessibility-label :send-transaction-button
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy/prepare-transaction-from-wallet account])}])
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/share)
|
|
||||||
:icon :main-icons/share
|
|
||||||
:accessibility-label :share-account-button
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy/share-popover (:address account)])}]
|
|
||||||
(when-not wallet
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/hide)
|
|
||||||
:icon :main-icons/hide
|
|
||||||
:accessibility-label :hide-account-button
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy.accounts/save-account account {:hidden true}])}])])
|
|
||||||
|
|
||||||
(defn add-account
|
|
||||||
[]
|
|
||||||
(let [keycard? @(re-frame/subscribe [:keycard-multiaccount?])]
|
|
||||||
[react/view
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (i18n/label :t/generate-a-new-account)
|
|
||||||
:theme :accent
|
|
||||||
:icon :main-icons/add
|
|
||||||
:accessibility-label :add-account-sheet-generate
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy.accounts/start-adding-new-account
|
|
||||||
{:type :generate}])}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/add-a-watch-account)
|
|
||||||
:icon :main-icons/show
|
|
||||||
:accessibility-label :add-account-sheet-watch
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy.accounts/start-adding-new-account
|
|
||||||
{:type :watch}])}]
|
|
||||||
(when-not keycard?
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (i18n/label :t/enter-a-seed-phrase)
|
|
||||||
:theme :accent
|
|
||||||
:icon :main-icons/text
|
|
||||||
:accessibility-label :add-account-sheet-seed
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy.accounts/start-adding-new-account
|
|
||||||
{:type :seed}])}])
|
|
||||||
(when-not keycard?
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (i18n/label :t/enter-a-private-key)
|
|
||||||
:theme :accent
|
|
||||||
:icon :main-icons/address
|
|
||||||
:accessibility-label :add-account-sheet-private-key
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy.accounts/start-adding-new-account
|
|
||||||
{:type :key}])}])]))
|
|
||||||
|
|
||||||
(defn account-settings
|
|
||||||
[]
|
|
||||||
[react/view
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/account-settings)
|
|
||||||
:accessibility-label :account-settings-bottom-sheet
|
|
||||||
:icon :main-icons/info
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:navigate-to :account-settings])}]])
|
|
|
@ -1,165 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.accounts.styles
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]))
|
|
||||||
|
|
||||||
(def dot-size 6)
|
|
||||||
|
|
||||||
(def dot-container
|
|
||||||
{:height 200
|
|
||||||
:flex-direction :column
|
|
||||||
:flex-wrap :wrap
|
|
||||||
:padding-horizontal 8})
|
|
||||||
|
|
||||||
(defn dot-selector
|
|
||||||
[]
|
|
||||||
{:flex-direction :row
|
|
||||||
:justify-content :space-between
|
|
||||||
:align-items :center})
|
|
||||||
|
|
||||||
(defn dot-style
|
|
||||||
[selected]
|
|
||||||
{:background-color (if selected colors/blue colors/blue-light)
|
|
||||||
:overflow :hidden
|
|
||||||
:opacity 1
|
|
||||||
:margin-horizontal 3
|
|
||||||
:width dot-size
|
|
||||||
:height dot-size
|
|
||||||
:border-radius 3})
|
|
||||||
|
|
||||||
(defn container
|
|
||||||
[{:keys [minimized]}]
|
|
||||||
(when-not minimized
|
|
||||||
{:padding-bottom 8
|
|
||||||
:padding-horizontal 16}))
|
|
||||||
|
|
||||||
(defn value-container
|
|
||||||
[{:keys [minimized animation]}]
|
|
||||||
(when minimized
|
|
||||||
{:opacity animation}))
|
|
||||||
|
|
||||||
(defn value-text
|
|
||||||
[{:keys [minimized]}]
|
|
||||||
{:font-size (if minimized 20 32)
|
|
||||||
:line-height 40
|
|
||||||
:color colors/black})
|
|
||||||
|
|
||||||
(defn accounts-mnemonic
|
|
||||||
[{:keys [animation]}]
|
|
||||||
{:opacity (if animation 1 0)
|
|
||||||
:flex 1
|
|
||||||
:justify-content :center
|
|
||||||
:position :absolute
|
|
||||||
:top 0
|
|
||||||
:bottom 0
|
|
||||||
:left 0})
|
|
||||||
|
|
||||||
(def card-margin 8)
|
|
||||||
(defn page-width
|
|
||||||
[card-width]
|
|
||||||
(+ card-width (* card-margin 2)))
|
|
||||||
|
|
||||||
(defn card-common
|
|
||||||
[card-width]
|
|
||||||
{:margin card-margin
|
|
||||||
:width card-width
|
|
||||||
:height 82
|
|
||||||
:border-radius 16})
|
|
||||||
|
|
||||||
(defn card
|
|
||||||
[color card-width]
|
|
||||||
(merge (card-common card-width)
|
|
||||||
{:background-color (if (string/blank? color)
|
|
||||||
colors/blue
|
|
||||||
color)
|
|
||||||
:justify-content :space-between
|
|
||||||
:padding-horizontal 12
|
|
||||||
:padding-top 12
|
|
||||||
:padding-bottom 10}))
|
|
||||||
|
|
||||||
(defn add-card
|
|
||||||
[card-width]
|
|
||||||
(merge (card-common card-width)
|
|
||||||
{:background-color colors/white
|
|
||||||
:flex-direction :row
|
|
||||||
:border-width 1
|
|
||||||
:border-color colors/gray-lighter
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center}))
|
|
||||||
|
|
||||||
(def add-text
|
|
||||||
{:color colors/blue
|
|
||||||
:margin-left 8
|
|
||||||
:font-weight "500"
|
|
||||||
:font-size 15
|
|
||||||
:line-height 22})
|
|
||||||
|
|
||||||
(def card-name
|
|
||||||
{:color colors/white-persist
|
|
||||||
:font-weight "500"
|
|
||||||
:font-size 15
|
|
||||||
:line-height 22})
|
|
||||||
|
|
||||||
(def card-address
|
|
||||||
{:number-of-lines 1
|
|
||||||
:ellipsize-mode :middle
|
|
||||||
:size :small
|
|
||||||
:monospace true
|
|
||||||
:style {:width 110
|
|
||||||
:font-size 15
|
|
||||||
:line-height 22
|
|
||||||
:color colors/white-transparent-70-persist}})
|
|
||||||
|
|
||||||
(def card-value
|
|
||||||
{:color colors/white-persist
|
|
||||||
:font-size 22
|
|
||||||
:font-weight "500"})
|
|
||||||
|
|
||||||
(def card-value-currency
|
|
||||||
{:color colors/white-persist
|
|
||||||
:font-size 22
|
|
||||||
:font-weight "500"})
|
|
||||||
|
|
||||||
(def card-icon-more
|
|
||||||
{:border-radius 32
|
|
||||||
:width 36
|
|
||||||
:height 36
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:background-color colors/black-transparent})
|
|
||||||
|
|
||||||
(def card-icon-type
|
|
||||||
{:border-radius 32
|
|
||||||
:width 36
|
|
||||||
:height 36
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:margin-left :auto
|
|
||||||
:margin-right 12
|
|
||||||
:background-color colors/white-persist})
|
|
||||||
|
|
||||||
(def send-button-container
|
|
||||||
{:position :absolute
|
|
||||||
:z-index 2
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center
|
|
||||||
:left 0
|
|
||||||
:right 0
|
|
||||||
:bottom 56
|
|
||||||
:height 40})
|
|
||||||
|
|
||||||
(defn send-button
|
|
||||||
[]
|
|
||||||
{:width 40
|
|
||||||
:height 40
|
|
||||||
:background-color colors/blue
|
|
||||||
:border-radius 20
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center
|
|
||||||
:shadow-offset {:width 0 :height 1}
|
|
||||||
:shadow-radius 6
|
|
||||||
:shadow-opacity 1
|
|
||||||
:shadow-color (if (colors/dark?)
|
|
||||||
"rgba(0, 0, 0, 0.75)"
|
|
||||||
"rgba(0, 12, 63, 0.2)")
|
|
||||||
:elevation 2})
|
|
|
@ -1,302 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.accounts.views
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.keycard.login :as keycard.login]
|
|
||||||
[legacy.status-im.qr-scanner.core :as qr-scanner]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.core :as components.core]
|
|
||||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.screens.wallet.account.views :as account.views]
|
|
||||||
[legacy.status-im.ui.screens.wallet.accounts.common :as common]
|
|
||||||
[legacy.status-im.ui.screens.wallet.accounts.sheets :as sheets]
|
|
||||||
[legacy.status-im.ui.screens.wallet.accounts.styles :as styles]
|
|
||||||
[legacy.status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto]
|
|
||||||
[quo.core :as quo]
|
|
||||||
[quo.foundations.colors :as quo.colors]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[react-native.reanimated :as reanimated]
|
|
||||||
[react-native.safe-area :as safe-area]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n])
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
|
||||||
|
|
||||||
(views/defview account-card
|
|
||||||
[{:keys [name color address type wallet] :as account} keycard? card-width]
|
|
||||||
(views/letsubs [currency [:wallet-legacy/currency]
|
|
||||||
portfolio-value [:account-portfolio-value address]
|
|
||||||
prices-loading? [:prices-loading?]]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch [:navigate-to :wallet-account account])
|
|
||||||
:accessibility-label (str "accountcard" name)}
|
|
||||||
[react/view {:style (styles/card color card-width)}
|
|
||||||
[react/view {:flex-direction :row :align-items :center :justify-content :space-between}
|
|
||||||
[react/text {:style styles/card-name} name]
|
|
||||||
[components.core/text styles/card-address
|
|
||||||
address]]
|
|
||||||
[react/view {:flex-direction :row :align-items :center :justify-content :space-between}
|
|
||||||
[react/view {:style {:flex-direction :row}}
|
|
||||||
(if prices-loading?
|
|
||||||
[react/small-loading-indicator :colors/white-persist]
|
|
||||||
[react/text
|
|
||||||
{:style styles/card-value
|
|
||||||
:accessibility-label "account-total-value"} portfolio-value])
|
|
||||||
[react/text {:style styles/card-value-currency} (str " " (:code currency))]]
|
|
||||||
(let [icon (cond
|
|
||||||
(= type :watch)
|
|
||||||
:main-icons/show
|
|
||||||
|
|
||||||
(and (not= type :watch) keycard?)
|
|
||||||
:main-icons/keycard-account)]
|
|
||||||
(when icon
|
|
||||||
[icons/icon icon
|
|
||||||
{:container-style styles/card-icon-type
|
|
||||||
:color color}]))
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:style styles/card-icon-more
|
|
||||||
:on-press #(re-frame/dispatch
|
|
||||||
[:bottom-sheet/show-sheet-old
|
|
||||||
{:content (fn [] [sheets/account-card-actions account type wallet])
|
|
||||||
:content-height 130}])}
|
|
||||||
[icons/icon :main-icons/more {:color colors/white-persist}]]]]]))
|
|
||||||
|
|
||||||
(defn add-card
|
|
||||||
[card-width]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content sheets/add-account
|
|
||||||
:content-height 260}])
|
|
||||||
:accessibility-label "add-new-account"}
|
|
||||||
[react/view {:style (styles/add-card card-width)}
|
|
||||||
[icons/icon :main-icons/add-circle {:color colors/blue}]
|
|
||||||
[react/text {:style styles/add-text} (i18n/label :t/add-account)]]])
|
|
||||||
|
|
||||||
(views/defview assets
|
|
||||||
[]
|
|
||||||
(views/letsubs [{:keys [tokens]} [:wallet-legacy/all-visible-assets-with-values]
|
|
||||||
currency [:wallet-legacy/currency]]
|
|
||||||
[:<>
|
|
||||||
(for [item tokens]
|
|
||||||
^{:key (:name item)}
|
|
||||||
[common/render-asset item nil nil (:code currency)])]))
|
|
||||||
|
|
||||||
(views/defview send-button
|
|
||||||
[]
|
|
||||||
(views/letsubs [account [:multiaccount/default-account]]
|
|
||||||
[react/view styles/send-button-container
|
|
||||||
[components.core/button
|
|
||||||
{:accessibility-label :send-transaction-button
|
|
||||||
:type :scale
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy/prepare-transaction-from-wallet
|
|
||||||
account])}
|
|
||||||
[react/view (styles/send-button)
|
|
||||||
[icons/icon :main-icons/send {:color colors/white-persist}]]]]))
|
|
||||||
|
|
||||||
(defn dot
|
|
||||||
[]
|
|
||||||
(fn [{:keys [selected]}]
|
|
||||||
[react/view {:style (styles/dot-style selected)}]))
|
|
||||||
|
|
||||||
(defn dots-selector
|
|
||||||
[{:keys [n selected]}]
|
|
||||||
[react/view {:style (styles/dot-selector)}
|
|
||||||
(for [i (range n)]
|
|
||||||
^{:key i}
|
|
||||||
[dot {:selected (= selected i)}])])
|
|
||||||
|
|
||||||
;;ACCOUNTS OLD
|
|
||||||
(views/defview accounts-old
|
|
||||||
[]
|
|
||||||
(views/letsubs [accounts [:multiaccount/visible-accounts]
|
|
||||||
keycard? [:keycard-multiaccount?]
|
|
||||||
window-width [:dimensions/window-width]
|
|
||||||
index (reagent/atom 0)]
|
|
||||||
(let [card-width (quot window-width 1.1)
|
|
||||||
page-width (styles/page-width card-width)]
|
|
||||||
[react/view
|
|
||||||
{:style {:align-items :center
|
|
||||||
:flex 1
|
|
||||||
:justify-content :flex-end}}
|
|
||||||
[react/scroll-view
|
|
||||||
{:horizontal true
|
|
||||||
:deceleration-rate "fast"
|
|
||||||
:snap-to-interval page-width
|
|
||||||
:shows-horizontal-scroll-indicator false
|
|
||||||
:scroll-event-throttle 64
|
|
||||||
:on-scroll #(let [x (.-nativeEvent.contentOffset.x ^js %)]
|
|
||||||
(reset! index (Math/max (Math/round (/ x page-width))
|
|
||||||
0)))}
|
|
||||||
[react/view styles/dot-container
|
|
||||||
(doall
|
|
||||||
(for [account accounts]
|
|
||||||
^{:key account}
|
|
||||||
[account-card account keycard? card-width]))
|
|
||||||
[add-card card-width]]]
|
|
||||||
(let [columns (Math/ceil (/ (inc (count accounts)) 2))
|
|
||||||
totalwidth (* (styles/page-width card-width) columns)
|
|
||||||
n (Math/ceil (/ totalwidth window-width))]
|
|
||||||
(when (> n 1)
|
|
||||||
[dots-selector
|
|
||||||
{:selected @index
|
|
||||||
:n n}]))])))
|
|
||||||
|
|
||||||
;;TOTAL VALUE OLD
|
|
||||||
(views/defview total-value-old
|
|
||||||
[{:keys [animation minimized]}]
|
|
||||||
(views/letsubs [currency [:wallet-legacy/currency]
|
|
||||||
portfolio-value [:portfolio-value]
|
|
||||||
empty-balances? [:empty-balances?]
|
|
||||||
frozen-card? [:keycard/frozen-card?]
|
|
||||||
{:keys [mnemonic]} [:profile/profile]]
|
|
||||||
[reanimated/view {:style (styles/container {:minimized minimized})}
|
|
||||||
(when (or
|
|
||||||
(and frozen-card? minimized)
|
|
||||||
(and mnemonic minimized (not empty-balances?)))
|
|
||||||
[reanimated/view {:style (styles/accounts-mnemonic {:animation animation})}
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch
|
|
||||||
(if frozen-card?
|
|
||||||
[::keycard.login/reset-pin]
|
|
||||||
[:navigate-to :backup-seed]))}
|
|
||||||
[react/view
|
|
||||||
{:flex-direction :row
|
|
||||||
:align-items :center}
|
|
||||||
[react/view
|
|
||||||
{:width 14
|
|
||||||
:height 14
|
|
||||||
:background-color colors/gray
|
|
||||||
:border-radius 7
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center
|
|
||||||
:margin-right 9}
|
|
||||||
[react/text
|
|
||||||
{:style {:color colors/white
|
|
||||||
:font-size 13
|
|
||||||
:font-weight "700"}}
|
|
||||||
"!"]]
|
|
||||||
[react/text
|
|
||||||
{:style {:color colors/gray}
|
|
||||||
:accessibility-label :back-up-your-seed-phrase-warning}
|
|
||||||
(if frozen-card?
|
|
||||||
(i18n/label :t/your-card-is-frozen)
|
|
||||||
(i18n/label :t/back-up-your-seed-phrase))]]]])
|
|
||||||
|
|
||||||
[reanimated/view
|
|
||||||
{:style (styles/value-container {:minimized minimized
|
|
||||||
:animation animation})
|
|
||||||
:pointer-events :none}
|
|
||||||
[reanimated/view {:style {:justify-content :center}}
|
|
||||||
[components.core/text
|
|
||||||
{:animated? true
|
|
||||||
:weight :semi-bold
|
|
||||||
:style (styles/value-text {:minimized minimized})}
|
|
||||||
portfolio-value
|
|
||||||
[components.core/text
|
|
||||||
{:animated? true
|
|
||||||
:size :inherit
|
|
||||||
:weight :inherit
|
|
||||||
:color :secondary}
|
|
||||||
(str " " (:code currency))]]]]
|
|
||||||
(when-not minimized
|
|
||||||
[reanimated/view
|
|
||||||
[components.core/text {:color :secondary}
|
|
||||||
(i18n/label :t/wallet-total-value)]])]))
|
|
||||||
|
|
||||||
(views/defview total-value
|
|
||||||
[]
|
|
||||||
(views/letsubs [currency [:wallet-legacy/currency]
|
|
||||||
portfolio-value [:portfolio-value]]
|
|
||||||
[react/view {:padding-vertical 12}
|
|
||||||
[quo/text (i18n/label :t/wallet-total-value)]
|
|
||||||
[quo/text {:size :heading-1 :weight :semi-bold}
|
|
||||||
(str portfolio-value " " (:code currency))]
|
|
||||||
[react/scroll-view {:horizontal true}]]))
|
|
||||||
|
|
||||||
(views/defview accounts
|
|
||||||
[selected-account-atom]
|
|
||||||
(views/letsubs [visible-accounts [:multiaccount/visible-accounts]]
|
|
||||||
(do
|
|
||||||
(reset! selected-account-atom (:address (first visible-accounts)))
|
|
||||||
(let [accounts-data (for [account visible-accounts]
|
|
||||||
{:label (:name account)
|
|
||||||
:id (:address account)})]
|
|
||||||
[react/scroll-view
|
|
||||||
{:horizontal true
|
|
||||||
:shows-horizontal-scroll-indicator false
|
|
||||||
:scroll-event-throttle 64
|
|
||||||
:margin-top 12
|
|
||||||
:margin-bottom 20}
|
|
||||||
[react/view {:flex-direction :row}
|
|
||||||
[quo/tabs
|
|
||||||
{:default-active (:address (first visible-accounts))
|
|
||||||
:on-change #(reset! selected-account-atom %)
|
|
||||||
:data accounts-data}]
|
|
||||||
[quo/button
|
|
||||||
{:type :grey
|
|
||||||
:size 32
|
|
||||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content sheets/add-account
|
|
||||||
:content-height 260}])}
|
|
||||||
"Add account"]]]))))
|
|
||||||
|
|
||||||
(defn accounts-overview
|
|
||||||
[]
|
|
||||||
(let [mnemonic @(re-frame/subscribe [:mnemonic])
|
|
||||||
selected-account-atom (reagent/atom nil)]
|
|
||||||
(fn []
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:padding-top (safe-area/get-top)
|
|
||||||
:background-color (quo.colors/theme-colors quo.colors/neutral-5
|
|
||||||
quo.colors/neutral-95)}}
|
|
||||||
[react/view {:padding-horizontal 20}
|
|
||||||
[react/view {:flex-direction :row :height 56 :align-items :center :justify-content :flex-end}
|
|
||||||
[quo/button
|
|
||||||
{:icon true
|
|
||||||
:size 32
|
|
||||||
:type :grey
|
|
||||||
:accessibility-label :accounts-qr-code
|
|
||||||
:on-press #(re-frame/dispatch
|
|
||||||
[::qr-scanner/scan-code
|
|
||||||
{:handler :wallet-legacy.send/qr-scanner-result}])}
|
|
||||||
:i/placeholder]
|
|
||||||
[react/view {:width 12}]
|
|
||||||
[quo/button
|
|
||||||
{:icon true
|
|
||||||
:size 32
|
|
||||||
:type :grey
|
|
||||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content (sheets/accounts-options mnemonic)}])
|
|
||||||
:accessibility-label :accounts-more-options}
|
|
||||||
:i/placeholder]]
|
|
||||||
[total-value]
|
|
||||||
[accounts selected-account-atom]]
|
|
||||||
[account.views/account-new @selected-account-atom]])))
|
|
||||||
|
|
||||||
(defn accounts-overview-old
|
|
||||||
[]
|
|
||||||
(let [mnemonic @(re-frame/subscribe [:mnemonic])
|
|
||||||
mainnet? @(re-frame/subscribe [:mainnet?])]
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1}}
|
|
||||||
[components.core/animated-header
|
|
||||||
{:extended-header total-value-old
|
|
||||||
:refresh-control common/refresh-control
|
|
||||||
:refreshing-sub (re-frame/subscribe [:wallet-legacy/refreshing-history?])
|
|
||||||
:refreshing-counter common/updates-counter
|
|
||||||
:use-insets true
|
|
||||||
:right-accessories [{:on-press #(re-frame/dispatch
|
|
||||||
[::qr-scanner/scan-code
|
|
||||||
{:handler :wallet-legacy.send/qr-scanner-result}])
|
|
||||||
:icon :main-icons/qr
|
|
||||||
:accessibility-label :accounts-qr-code}
|
|
||||||
{:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content (sheets/accounts-options
|
|
||||||
mnemonic)}])
|
|
||||||
:icon :main-icons/more
|
|
||||||
:accessibility-label :accounts-more-options}]}
|
|
||||||
[accounts-old]
|
|
||||||
(when mainnet?
|
|
||||||
[buy-crypto/banner])
|
|
||||||
[assets]
|
|
||||||
[react/view {:height 68}]]
|
|
||||||
[send-button]]))
|
|
|
@ -1,38 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.accounts-manage.views
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.list.views :as list]
|
|
||||||
[legacy.status-im.utils.utils :as utils]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
(defn render-account
|
|
||||||
[_]
|
|
||||||
(reagent/create-class
|
|
||||||
{:should-component-update
|
|
||||||
(fn [_ [_ old-item] [_ new-item]]
|
|
||||||
(not= (:hidden old-item) (:hidden new-item)))
|
|
||||||
:reagent-render
|
|
||||||
(fn [{:keys [hidden name address wallet] :as account}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:accessory [icons/icon
|
|
||||||
(if hidden :main-icos/hide :main-icos/show)
|
|
||||||
(merge {:accessibility-label (if hidden :hide-icon :show-icon)}
|
|
||||||
(when wallet {:color colors/gray}))]
|
|
||||||
:animated-accessory? false
|
|
||||||
:animated false
|
|
||||||
:disabled wallet
|
|
||||||
:title name
|
|
||||||
:subtitle (utils/get-shortened-checksum-address address)
|
|
||||||
:on-press #(rf/dispatch [:wallet-legacy.accounts/save-account account
|
|
||||||
{:hidden (not hidden)}])}])}))
|
|
||||||
|
|
||||||
(defn manage
|
|
||||||
[]
|
|
||||||
(let [accounts (rf/sub [:profile/wallet-accounts])]
|
|
||||||
[list/flat-list
|
|
||||||
{:key-fn :address
|
|
||||||
:data accounts
|
|
||||||
:render-fn render-account}]))
|
|
|
@ -1,173 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.add-new.views
|
|
||||||
(:require-macros [legacy.status-im.utils.views :refer [defview letsubs]])
|
|
||||||
(:require
|
|
||||||
[cljs.spec.alpha :as spec]
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.multiaccounts.db :as multiaccounts.db]
|
|
||||||
[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]
|
|
||||||
[legacy.status-im.ui.components.toolbar :as toolbar]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[legacy.status-im.ui.screens.wallet.account-settings.views :as account-settings]
|
|
||||||
[native-module.core :as native-module]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.security.core :as security]))
|
|
||||||
|
|
||||||
(defn add-account-topbar
|
|
||||||
[type]
|
|
||||||
(let [title (case type
|
|
||||||
:generate :t/generate-an-account
|
|
||||||
:watch :t/add-watch-account
|
|
||||||
:seed :t/add-seed-account
|
|
||||||
:key :t/add-private-key-account
|
|
||||||
"")]
|
|
||||||
[topbar/topbar
|
|
||||||
(merge {:title (i18n/label title)}
|
|
||||||
(when (= type :watch)
|
|
||||||
{:right-accessories
|
|
||||||
[{:icon :qr
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.add-new/qr-scanner
|
|
||||||
{:handler
|
|
||||||
:wallet-legacy.add-new/qr-scanner-result}])}]}))]))
|
|
||||||
|
|
||||||
(defn common-settings
|
|
||||||
[account]
|
|
||||||
[react/view {:margin-horizontal 16}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/account-name)
|
|
||||||
:auto-focus false
|
|
||||||
:default-value (:name account)
|
|
||||||
:accessibility-label :enter-account-name
|
|
||||||
:placeholder (i18n/label :t/account-name)
|
|
||||||
:on-change-text #(re-frame/dispatch [:set-in [:add-account :account :name] %])}]
|
|
||||||
[react/text {:style {:margin-top 30}} (i18n/label :t/account-color)]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch
|
|
||||||
[:show-popover
|
|
||||||
{:view [account-settings/colors-popover (:color account)
|
|
||||||
(fn [new-color]
|
|
||||||
(re-frame/dispatch [:set-in [:add-account :account :color] new-color])
|
|
||||||
(re-frame/dispatch [:hide-popover]))]
|
|
||||||
:style {:max-height "60%"}}])}
|
|
||||||
[react/view
|
|
||||||
{:height 52
|
|
||||||
:margin-top 12
|
|
||||||
:background-color (:color account)
|
|
||||||
:border-radius 8
|
|
||||||
:align-items :flex-end
|
|
||||||
:justify-content :center
|
|
||||||
:padding-right 12}
|
|
||||||
[icons/icon :main-icons/dropdown {:color colors/white}]]]])
|
|
||||||
|
|
||||||
(defn settings
|
|
||||||
[{:keys [type scanned-address password-error account-error]}
|
|
||||||
entered-password]
|
|
||||||
[react/view
|
|
||||||
{:padding-horizontal 16
|
|
||||||
:padding-vertical 16}
|
|
||||||
(if (= type :watch)
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/wallet-key-title)
|
|
||||||
:auto-focus false
|
|
||||||
:default-value scanned-address
|
|
||||||
:monospace true
|
|
||||||
:placeholder (i18n/label :t/enter-address)
|
|
||||||
:accessibility-label :add-account-enter-watch-address
|
|
||||||
:on-change-text #(re-frame/dispatch [:wallet-legacy.accounts/set-account-to-watch %])}]
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/password)
|
|
||||||
:show-cancel false
|
|
||||||
:auto-focus false
|
|
||||||
:placeholder (i18n/label :t/enter-your-password)
|
|
||||||
:secure-text-entry true
|
|
||||||
:text-content-type :none
|
|
||||||
:accessibility-label :add-account-enter-password
|
|
||||||
:bottom-value 0
|
|
||||||
:error (when password-error (i18n/label :t/add-account-incorrect-password))
|
|
||||||
:on-change-text #(do
|
|
||||||
(re-frame/dispatch [:set-in [:add-account :password-error] nil])
|
|
||||||
(reset! entered-password %))}])
|
|
||||||
(when (= type :seed)
|
|
||||||
[react/view {:padding-top 16}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/recovery-phrase)
|
|
||||||
:auto-focus false
|
|
||||||
:placeholder (i18n/label :t/multiaccounts-recover-enter-phrase-title)
|
|
||||||
:auto-correct false
|
|
||||||
:keyboard-type :visible-password
|
|
||||||
:multiline true
|
|
||||||
:height 95
|
|
||||||
:error account-error
|
|
||||||
:accessibility-label :add-account-enter-seed
|
|
||||||
:monospace true
|
|
||||||
:on-change-text
|
|
||||||
#(do
|
|
||||||
(re-frame/dispatch [:set-in [:add-account :account-error] nil])
|
|
||||||
(re-frame/dispatch [:set-in [:add-account :seed]
|
|
||||||
(security/mask-data (string/lower-case %))]))}]])
|
|
||||||
(when (= type :key)
|
|
||||||
[react/view {:margin-top 30}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/private-key)
|
|
||||||
:auto-focus false
|
|
||||||
:placeholder (i18n/label :t/enter-a-private-key)
|
|
||||||
:auto-correct false
|
|
||||||
:keyboard-type :visible-password
|
|
||||||
:error account-error
|
|
||||||
:secure-text-entry true
|
|
||||||
:accessibility-label :add-account-enter-private-key
|
|
||||||
:text-content-type :none
|
|
||||||
:on-change-text
|
|
||||||
#(do
|
|
||||||
(re-frame/dispatch [:set-in [:add-account :account-error] nil])
|
|
||||||
(re-frame/dispatch [:set-in [:add-account :private-key] (security/mask-data %)]))}]])])
|
|
||||||
|
|
||||||
(defn pin
|
|
||||||
[]
|
|
||||||
[react/view])
|
|
||||||
|
|
||||||
(defview add-account-view
|
|
||||||
[]
|
|
||||||
(letsubs [{:keys [type account] :as add-account} [:add-account]
|
|
||||||
add-account-disabled? [:add-account-disabled?]
|
|
||||||
entered-password (reagent/atom "")
|
|
||||||
keycard? [:keycard-multiaccount?]]
|
|
||||||
[react/keyboard-avoiding-view
|
|
||||||
{:style {:flex 1}
|
|
||||||
:ignore-offset true}
|
|
||||||
[add-account-topbar type]
|
|
||||||
[react/scroll-view
|
|
||||||
{:keyboard-should-persist-taps :handled
|
|
||||||
:style {:flex 1 :padding-top 20}}
|
|
||||||
(when (or (not keycard?)
|
|
||||||
(= type :watch))
|
|
||||||
[settings add-account entered-password])
|
|
||||||
[common-settings account]]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:right
|
|
||||||
[quo/button
|
|
||||||
{:type :secondary
|
|
||||||
:after :main-icon/next
|
|
||||||
:accessibility-label :add-account-add-account-button
|
|
||||||
:on-press
|
|
||||||
(if (and keycard?
|
|
||||||
(not= type :watch))
|
|
||||||
#(re-frame/dispatch [:keycard/new-account-pin-sheet
|
|
||||||
{:view {:content pin
|
|
||||||
:height 256}}])
|
|
||||||
#(re-frame/dispatch [:wallet-legacy.accounts/add-new-account
|
|
||||||
(native-module/sha3 @entered-password)]))
|
|
||||||
:disabled
|
|
||||||
(or add-account-disabled?
|
|
||||||
(and
|
|
||||||
(not (= type :watch))
|
|
||||||
(and
|
|
||||||
(not keycard?)
|
|
||||||
(not (spec/valid? ::multiaccounts.db/password
|
|
||||||
@entered-password)))))}
|
|
||||||
(i18n/label :t/add-account)]}]]))
|
|
|
@ -1,34 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.buy-crypto.sheets
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]))
|
|
||||||
|
|
||||||
;; This needs to be a function because `colors/x` is a mutable reference
|
|
||||||
;; and changes dynamically based on the appearance settings
|
|
||||||
(defn banner-container
|
|
||||||
[]
|
|
||||||
{:margin-horizontal 16
|
|
||||||
:flex-direction :row
|
|
||||||
:justify-content :space-between
|
|
||||||
:align-items :center
|
|
||||||
:flex 1
|
|
||||||
:margin-top 16
|
|
||||||
:border-radius 16
|
|
||||||
:margin-bottom 8
|
|
||||||
:padding-horizontal 12
|
|
||||||
:padding-vertical 5
|
|
||||||
:background-color colors/blue-light})
|
|
||||||
|
|
||||||
(defn highlight-container
|
|
||||||
[]
|
|
||||||
{:padding 4
|
|
||||||
:justify-content :center
|
|
||||||
:border-radius 4
|
|
||||||
:background-color colors/blue})
|
|
||||||
|
|
||||||
(def highlight-text
|
|
||||||
{:text-transform :uppercase
|
|
||||||
:color "#FFFFFF"})
|
|
||||||
|
|
||||||
(def icon
|
|
||||||
{:width 68
|
|
||||||
:height 36})
|
|
|
@ -1,167 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.buy-crypto.views
|
|
||||||
(:require
|
|
||||||
[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.list.views :as list]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[legacy.status-im.ui.components.webview :as components.webview]
|
|
||||||
[legacy.status-im.ui.screens.browser.views :as browser.views]
|
|
||||||
[legacy.status-im.ui.screens.chat.photos :as photos]
|
|
||||||
[legacy.status-im.ui.screens.wallet.buy-crypto.sheets :as sheets]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n])
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
|
||||||
|
|
||||||
(def learn-more-url "")
|
|
||||||
|
|
||||||
(def webview-ref (atom nil))
|
|
||||||
|
|
||||||
(defn on-buy-crypto-pressed
|
|
||||||
[]
|
|
||||||
(re-frame/dispatch [:buy-crypto.ui/open-screen]))
|
|
||||||
|
|
||||||
(defn render-on-ramp
|
|
||||||
[{:keys [name fees logo-url description] :as on-ramp}]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch [:open-modal :buy-crypto-website on-ramp])
|
|
||||||
:style {:flex 1}}
|
|
||||||
[list.item/list-item
|
|
||||||
{:title [react/view {:style {:flex 1}}
|
|
||||||
[quo/text
|
|
||||||
{:size :large
|
|
||||||
:weight :bold}
|
|
||||||
name]
|
|
||||||
[quo/text {} description]]
|
|
||||||
:subtitle [react/view {:style {:flex 1}}
|
|
||||||
[quo/text
|
|
||||||
{:size :small
|
|
||||||
:color :secondary} fees]]
|
|
||||||
:icon [photos/photo logo-url {:size 40}]
|
|
||||||
:left-side-alignment :flex-start
|
|
||||||
:accessory :text}]])
|
|
||||||
|
|
||||||
(defn buy-crypto-header
|
|
||||||
[]
|
|
||||||
[react/view
|
|
||||||
{:padding-bottom 16
|
|
||||||
:align-items :center}
|
|
||||||
[react/view
|
|
||||||
{:padding-top 16
|
|
||||||
:padding-bottom 8}
|
|
||||||
[quo/text
|
|
||||||
{:weight :bold
|
|
||||||
:size :x-large}
|
|
||||||
(i18n/label :t/buy-crypto)]]
|
|
||||||
[quo/text {:color :secondary}
|
|
||||||
(i18n/label :t/buy-crypto-choose-a-service)]
|
|
||||||
(when (seq learn-more-url)
|
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:browser.ui/open-url learn-more-url])}
|
|
||||||
[react/view {:padding-vertical 11}
|
|
||||||
[quo/text {:color :link} (i18n/label :t/learn-more)]]])])
|
|
||||||
|
|
||||||
(views/defview buy-crypto
|
|
||||||
[]
|
|
||||||
(views/letsubs [on-ramps [:buy-crypto/on-ramps]]
|
|
||||||
[list/flat-list
|
|
||||||
{:data on-ramps
|
|
||||||
:key-fn :site-url
|
|
||||||
:header [buy-crypto-header]
|
|
||||||
:render-fn render-on-ramp}]))
|
|
||||||
|
|
||||||
(defn website
|
|
||||||
[]
|
|
||||||
(let [has-loaded? (reagent/atom false)
|
|
||||||
initialized? (reagent/atom false)
|
|
||||||
{:keys [name
|
|
||||||
hostname
|
|
||||||
logo-url
|
|
||||||
site-url]}
|
|
||||||
@(re-frame/subscribe [:get-screen-params])]
|
|
||||||
;;it crashes on android , probably because of modal animation
|
|
||||||
(js/setTimeout #(reset! initialized? true) 500)
|
|
||||||
(fn []
|
|
||||||
;; overflow hidden needed for the crash on android
|
|
||||||
[react/view {:flex 1 :overflow :hidden}
|
|
||||||
[topbar/topbar
|
|
||||||
{:content [react/view
|
|
||||||
{:flex 1
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center}
|
|
||||||
[quo/text
|
|
||||||
{:weight :semi-bold}
|
|
||||||
(i18n/label :t/buy-crypto)]
|
|
||||||
[quo/text {:color :secondary}
|
|
||||||
hostname]]
|
|
||||||
:modal? true}]
|
|
||||||
(when-not @has-loaded?
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:position :absolute
|
|
||||||
:top 56
|
|
||||||
:left 0
|
|
||||||
:right 0
|
|
||||||
:z-index 1
|
|
||||||
:background-color "#ffffff"
|
|
||||||
:bottom 0
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center}}
|
|
||||||
[photos/photo logo-url {:size 40}]
|
|
||||||
[quo/text
|
|
||||||
{:size :x-large}
|
|
||||||
(i18n/label :t/opening-buy-crypto {:site name})]
|
|
||||||
[react/view {:style {:padding-horizontal 32}}
|
|
||||||
[quo/text
|
|
||||||
{:align :center
|
|
||||||
:color :secondary}
|
|
||||||
(i18n/label :t/buy-crypto-leaving)]]])
|
|
||||||
(when @initialized?
|
|
||||||
[components.webview/webview
|
|
||||||
{:onLoadEnd #(reset! has-loaded? true)
|
|
||||||
:ref #(reset! webview-ref %)
|
|
||||||
:on-permission-request #(browser.views/request-resources-access-for-page
|
|
||||||
(-> ^js % .-nativeEvent .-resources)
|
|
||||||
site-url
|
|
||||||
@webview-ref)
|
|
||||||
:java-script-enabled true
|
|
||||||
;; This is to avoid crashes on android devices due to
|
|
||||||
;; https://github.com/react-native-webview/react-native-webview/issues/1838
|
|
||||||
;; We can't disable hardware acceleration as we need to use camera
|
|
||||||
:style {:opacity 0.99}
|
|
||||||
:local-storage-enabled true
|
|
||||||
:source {:uri site-url}}])])))
|
|
||||||
|
|
||||||
(defn container
|
|
||||||
[]
|
|
||||||
(reagent/create-class
|
|
||||||
{:component-did-mount #(re-frame/dispatch [:buy-crypto.ui/loaded])
|
|
||||||
:reagent-render buy-crypto}))
|
|
||||||
|
|
||||||
(defn banner
|
|
||||||
[]
|
|
||||||
(fn []
|
|
||||||
[react/touchable-highlight {:on-press on-buy-crypto-pressed}
|
|
||||||
[react/view {:style (sheets/banner-container)}
|
|
||||||
[react/view {:flex-direction :row}
|
|
||||||
[react/view {:style (sheets/highlight-container)}
|
|
||||||
[quo/text
|
|
||||||
{:weight :bold
|
|
||||||
:size :tiny
|
|
||||||
:style sheets/highlight-text}
|
|
||||||
(i18n/label :t/new)]]
|
|
||||||
[react/view
|
|
||||||
{:style {:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:padding-left 8}}
|
|
||||||
[quo/text
|
|
||||||
{:size :large
|
|
||||||
:weight :medium
|
|
||||||
:color :link} (i18n/label :t/buy-crypto)]]]
|
|
||||||
[react/view
|
|
||||||
{:style {:align-content :flex-end
|
|
||||||
:align-self :flex-end}}
|
|
||||||
[react/image
|
|
||||||
{:source (icons/icon-source :buy-crypto)
|
|
||||||
:style sheets/icon}]]]]))
|
|
|
@ -1,314 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.collectibles.views
|
|
||||||
(:require
|
|
||||||
["react-native-svg" :refer (SvgUri)]
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
|
||||||
[legacy.status-im.react-native.resources :as resources]
|
|
||||||
[legacy.status-im.ui.components.accordion :as accordion]
|
|
||||||
[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.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.components.toastable-highlight :refer [toastable-highlight-view]]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as wallet.components]
|
|
||||||
[legacy.status-im.wallet.core :as wallet-legacy]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
(def svg-uri (reagent/adapt-react-class SvgUri))
|
|
||||||
|
|
||||||
(defn is-image?
|
|
||||||
[nft]
|
|
||||||
(and (seq (:image_url nft))
|
|
||||||
(not (string/ends-with? (:image_url nft) ".svg"))
|
|
||||||
(not (string/ends-with? (:image_url nft) ".mp4"))))
|
|
||||||
|
|
||||||
(defn is-vector?
|
|
||||||
[nft]
|
|
||||||
(and (seq (:image_url nft))
|
|
||||||
(string/ends-with? (:image_url nft) ".svg")))
|
|
||||||
|
|
||||||
(defn missing-image-placeholder
|
|
||||||
[]
|
|
||||||
[react/view
|
|
||||||
{:style {:width "100%"
|
|
||||||
:flex 1
|
|
||||||
:align-items :center
|
|
||||||
:border-radius 16
|
|
||||||
:background-color colors/gray-lighter
|
|
||||||
:justify-content :center
|
|
||||||
:aspect-ratio 1}}
|
|
||||||
[icons/icon :photo {:color colors/gray}]])
|
|
||||||
|
|
||||||
(defn nft-assets-skeleton
|
|
||||||
[num-assets]
|
|
||||||
[:<>
|
|
||||||
(for [i (range num-assets)]
|
|
||||||
^{:key i}
|
|
||||||
[react/view
|
|
||||||
{:style {:width "48%"
|
|
||||||
:margin-bottom 16}}
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:aspect-ratio 1
|
|
||||||
:border-width 1
|
|
||||||
:background-color colors/gray-transparent-10
|
|
||||||
:border-color colors/gray-lighter
|
|
||||||
:border-radius 16}}]])])
|
|
||||||
|
|
||||||
(defn nft-trait-card
|
|
||||||
[trait]
|
|
||||||
[react/view
|
|
||||||
{:style {:border-width 1
|
|
||||||
:border-radius 12
|
|
||||||
:margin-right 8
|
|
||||||
:padding-vertical 4
|
|
||||||
:padding-horizontal 8
|
|
||||||
:border-color colors/gray-lighter}}
|
|
||||||
[quo/text
|
|
||||||
{:size :small
|
|
||||||
:color :secondary}
|
|
||||||
(:trait_type trait)]
|
|
||||||
[quo/text {}
|
|
||||||
(:value trait)]])
|
|
||||||
|
|
||||||
(defn nft-traits-scroller
|
|
||||||
[traits]
|
|
||||||
[react/scroll-view
|
|
||||||
{:horizontal true
|
|
||||||
:deceleration-rate "fast"
|
|
||||||
:snap-to-alignment "start"
|
|
||||||
:shows-horizontal-scroll-indicator
|
|
||||||
false
|
|
||||||
:scroll-event-throttle 64
|
|
||||||
:style {:padding-left 16
|
|
||||||
:margin-vertical 16
|
|
||||||
:padding-bottom 8}}
|
|
||||||
(for [trait traits]
|
|
||||||
^{:key (:trait_type trait)}
|
|
||||||
[nft-trait-card trait])
|
|
||||||
|
|
||||||
;; spacer
|
|
||||||
[react/view
|
|
||||||
{:style {:height 40
|
|
||||||
:width 40}}]])
|
|
||||||
|
|
||||||
(defn no-assets-error
|
|
||||||
[]
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:justify-content :center
|
|
||||||
:padding 16
|
|
||||||
:margin-vertical 16
|
|
||||||
:align-items :center
|
|
||||||
:border-radius 16}}
|
|
||||||
[icons/icon :photo {:color colors/red}]
|
|
||||||
[quo/text
|
|
||||||
{:color :secondary
|
|
||||||
:style {:magin-top 8}}
|
|
||||||
(i18n/label :t/no-collectibles)]])
|
|
||||||
|
|
||||||
(defn render-asset
|
|
||||||
[{:keys [asset width clickable?]}]
|
|
||||||
[(if clickable? react/touchable-opacity react/view)
|
|
||||||
{:style
|
|
||||||
{:width width
|
|
||||||
:border-radius 16
|
|
||||||
:margin-bottom 16}
|
|
||||||
:on-press (when clickable? #(re-frame/dispatch [::wallet-legacy/show-nft-details asset]))
|
|
||||||
:accessibility-label
|
|
||||||
:nft-asset}
|
|
||||||
(cond
|
|
||||||
;; pngs and jpegs
|
|
||||||
(is-image? asset)
|
|
||||||
[react/image
|
|
||||||
{:style {:flex 1
|
|
||||||
:aspect-ratio 1
|
|
||||||
:border-width 1
|
|
||||||
:border-color colors/gray-lighter
|
|
||||||
:border-radius 16}
|
|
||||||
:source {:uri (:image_url asset)}}]
|
|
||||||
|
|
||||||
;; vectors
|
|
||||||
(is-vector? asset)
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:aspect-ratio 1
|
|
||||||
:border-width 1
|
|
||||||
:border-color colors/gray-lighter
|
|
||||||
:border-radius 16}}
|
|
||||||
[svg-uri
|
|
||||||
{:uri (:image_url asset)
|
|
||||||
:width "100%"
|
|
||||||
:height "100%"}]]
|
|
||||||
|
|
||||||
;; ¯\_(ツ)_/¯
|
|
||||||
:else [missing-image-placeholder])])
|
|
||||||
|
|
||||||
(defn nft-assets
|
|
||||||
[{:keys [num-assets address collectible-slug]}]
|
|
||||||
(let [assets (rf/sub [:wallet-legacy/collectible-assets-by-collection-and-address address
|
|
||||||
collectible-slug])
|
|
||||||
fetching? (rf/sub [:wallet-legacy/fetching-assets-by-collectible-slug collectible-slug])]
|
|
||||||
[react/view
|
|
||||||
{:flex 1
|
|
||||||
:flex-wrap :wrap
|
|
||||||
:justify-content :space-between
|
|
||||||
:flex-direction :row
|
|
||||||
:style {:padding-horizontal 16}}
|
|
||||||
(cond
|
|
||||||
fetching? [nft-assets-skeleton num-assets]
|
|
||||||
|
|
||||||
;; <shivekkhurana> OpenSea sometimes doesn't return an asset. This condition handles it
|
|
||||||
(and (not fetching?)
|
|
||||||
(not (seq assets)))
|
|
||||||
[no-assets-error]
|
|
||||||
|
|
||||||
(seq assets)
|
|
||||||
(for [asset assets]
|
|
||||||
^{:key (:id asset)}
|
|
||||||
[render-asset
|
|
||||||
{:asset asset
|
|
||||||
:clickable? true
|
|
||||||
:width "48%"}]))]))
|
|
||||||
|
|
||||||
(defn nft-collections
|
|
||||||
[address]
|
|
||||||
(let [collection (rf/sub [:wallet-legacy/collectible-collection address])]
|
|
||||||
[:<>
|
|
||||||
(for [[index collectible] (map-indexed vector collection)]
|
|
||||||
^{:key (:slug collectible)}
|
|
||||||
[accordion/section
|
|
||||||
{:title
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (:name collectible)
|
|
||||||
:text-size :large
|
|
||||||
:accessibility-label
|
|
||||||
(keyword (str "collection-" index))
|
|
||||||
:icon (if (seq (:image_url collectible))
|
|
||||||
[wallet.components/token-icon
|
|
||||||
{:style {:border-radius 40
|
|
||||||
:overflow :hidden
|
|
||||||
:border-width 1
|
|
||||||
:border-color colors/gray-lighter}
|
|
||||||
:source {:uri (:image_url collectible)}}]
|
|
||||||
:main-icons/photo)
|
|
||||||
:accessory :text
|
|
||||||
:accessory-text (:owned_asset_count collectible)}]]
|
|
||||||
:padding-vertical 0
|
|
||||||
:dropdown-margin-left -12
|
|
||||||
:open-container-style {:border-top-width 8
|
|
||||||
:border-bottom-width 8
|
|
||||||
:border-color colors/gray-lighter}
|
|
||||||
:on-open #(re-frame/dispatch
|
|
||||||
[::wallet-legacy/fetch-collectible-assets-by-owner-and-collection
|
|
||||||
address
|
|
||||||
(:slug collectible)
|
|
||||||
(:owned_asset_count collectible)])
|
|
||||||
:content [nft-assets
|
|
||||||
{:address address
|
|
||||||
:num-assets (:owned_asset_count collectible)
|
|
||||||
:collectible-slug (:slug collectible)}]}])]))
|
|
||||||
|
|
||||||
(defn enable-opensea-view
|
|
||||||
[]
|
|
||||||
[react/view {:style {:padding 16}}
|
|
||||||
[react/view
|
|
||||||
{:style {:border-color colors/gray-lighter
|
|
||||||
:border-width 1
|
|
||||||
:align-self :center
|
|
||||||
:padding 4
|
|
||||||
:border-radius 12}}
|
|
||||||
[react/image
|
|
||||||
{:source (resources/get-theme-image :collectible)
|
|
||||||
:style {:align-self :center
|
|
||||||
:resize-mode :contain}}]]
|
|
||||||
[quo/text
|
|
||||||
{:align :center
|
|
||||||
:style {:margin-vertical 16}}
|
|
||||||
(i18n/label :t/collectibles-leak-metadata)]
|
|
||||||
[react/view {:align-items :center}
|
|
||||||
[quo/button
|
|
||||||
{:accessibility-label :enable-opensea-nft-visibility
|
|
||||||
:on-press
|
|
||||||
#(re-frame/dispatch
|
|
||||||
[::multiaccounts.update/toggle-opensea-nfts-visiblity true])
|
|
||||||
:theme :main
|
|
||||||
:type :primary}
|
|
||||||
(i18n/label :t/display-collectibles)]]
|
|
||||||
[quo/text
|
|
||||||
{:size :small
|
|
||||||
:color :secondary
|
|
||||||
:align :center
|
|
||||||
:style {:margin-top 10}}
|
|
||||||
(i18n/label :t/disable-later-in-settings)]])
|
|
||||||
|
|
||||||
(defn nft-details-modal
|
|
||||||
[]
|
|
||||||
(let [nft (rf/sub [:wallet-legacy/selected-collectible])]
|
|
||||||
[react/scroll-view
|
|
||||||
[topbar/topbar
|
|
||||||
{:navigation {:icon :main-icons/close}
|
|
||||||
:border-bottom false}]
|
|
||||||
[react/view {:padding-horizontal 16}
|
|
||||||
[quo/text
|
|
||||||
{:size :large
|
|
||||||
:weight :bold}
|
|
||||||
(:name nft)]
|
|
||||||
[quo/text
|
|
||||||
{:size :small
|
|
||||||
:color :secondary
|
|
||||||
:style {:margin-top 4}}
|
|
||||||
(-> nft :collection :name)]
|
|
||||||
|
|
||||||
[render-asset
|
|
||||||
{:asset nft
|
|
||||||
:clickable? false
|
|
||||||
:width "100%"}]
|
|
||||||
|
|
||||||
[quo/text {:style {:margin-top 12}}
|
|
||||||
(:description nft)]]
|
|
||||||
|
|
||||||
(when (seq (:traits nft))
|
|
||||||
[nft-traits-scroller (:traits nft)])
|
|
||||||
|
|
||||||
;; seperator
|
|
||||||
[react/view
|
|
||||||
{:style {:border-bottom-width 1
|
|
||||||
:padding-top 8
|
|
||||||
:border-color colors/gray-lighter}}]
|
|
||||||
|
|
||||||
;; TODO <shivekkhurana>: Enable txns
|
|
||||||
;; [list/list-item {:title (i18n/label :t/wallet-send)
|
|
||||||
;; :icon :main-icons/send :accessibility-label :nft-send :theme :accent
|
|
||||||
;; :on-press #()}]
|
|
||||||
|
|
||||||
;; TODO <shivekkhurana>: What to do with share? Share links or share image?
|
|
||||||
;; [list/list-item {:title (i18n/label :t/share)
|
|
||||||
;; :theme :accent
|
|
||||||
;; :accessibility-label
|
|
||||||
;; :nft-share
|
|
||||||
;; :on-press #()
|
|
||||||
;; :icon :main-icons/share}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (i18n/label :t/view-on-opensea)
|
|
||||||
:theme :accent
|
|
||||||
:icon :main-icons/browser
|
|
||||||
:on-press #(re-frame/dispatch [:browser.ui/open-url (:permalink nft)])}]
|
|
||||||
(when (is-image? nft)
|
|
||||||
[toastable-highlight-view
|
|
||||||
;; the last string is an emoji. It might not show up in all editors but its there
|
|
||||||
{:toast-label (str (i18n/label :t/profile-picture-updated)) " " "😎"}
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (i18n/label :t/use-as-profile-picture)
|
|
||||||
:theme :accent
|
|
||||||
:on-press #(re-frame/dispatch [:profile.settings/save-profile-picture-from-url
|
|
||||||
(:image_url nft)])
|
|
||||||
:icon :main-icons/profile
|
|
||||||
:accessibility-label
|
|
||||||
:set-nft-as-pfp}]])]))
|
|
|
@ -1,13 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.components.styles
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]))
|
|
||||||
|
|
||||||
(defn separator
|
|
||||||
[]
|
|
||||||
{:height 1
|
|
||||||
:background-color colors/gray-lighter})
|
|
||||||
|
|
||||||
(defn separator-dark
|
|
||||||
[]
|
|
||||||
{:height 1
|
|
||||||
:background-color colors/black-transparent})
|
|
|
@ -1,22 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.components.views
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.screens.wallet.components.styles :as styles]))
|
|
||||||
|
|
||||||
(defn separator
|
|
||||||
[]
|
|
||||||
[react/view (styles/separator)])
|
|
||||||
|
|
||||||
(defn separator-dark
|
|
||||||
[]
|
|
||||||
[react/view (styles/separator-dark)])
|
|
||||||
|
|
||||||
(defn token-icon
|
|
||||||
[{:keys [style source image-style width height]}]
|
|
||||||
[react/view {:style style}
|
|
||||||
[react/image
|
|
||||||
{:source (if (fn? source) (source) source)
|
|
||||||
:style (merge
|
|
||||||
{:width (or width 40)
|
|
||||||
:height (or height 40)}
|
|
||||||
image-style)}]])
|
|
|
@ -1,171 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.custom-tokens.views
|
|
||||||
(:require-macros [legacy.status-im.utils.views :refer [defview letsubs]])
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.core :as quo]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.components.toolbar :as toolbar]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[utils.i18n :as i18n]))
|
|
||||||
|
|
||||||
(def debounce-timers (atom {}))
|
|
||||||
|
|
||||||
(defn debounce-and-save
|
|
||||||
[field-key value]
|
|
||||||
(let [timeout (get @debounce-timers field-key)]
|
|
||||||
(when timeout (js/clearTimeout timeout))
|
|
||||||
(swap! debounce-timers assoc
|
|
||||||
field-key
|
|
||||||
(js/setTimeout
|
|
||||||
#(re-frame/dispatch [:wallet-legacy.custom-token.ui/field-is-edited field-key
|
|
||||||
(string/trim value)])
|
|
||||||
500))))
|
|
||||||
|
|
||||||
(defview add-custom-token
|
|
||||||
[]
|
|
||||||
(letsubs [{:keys [contract name decimals in-progress? error error-name error-symbol]
|
|
||||||
:as m}
|
|
||||||
[:wallet-legacy/custom-token-screen]]
|
|
||||||
(let [sym (:symbol m)]
|
|
||||||
[react/keyboard-avoiding-view {:flex 1 :background-color colors/white}
|
|
||||||
[react/scroll-view
|
|
||||||
{:keyboard-should-persist-taps :handled
|
|
||||||
:style {:flex 1
|
|
||||||
:padding-horizontal 16}}
|
|
||||||
[react/view {:padding-vertical 8}
|
|
||||||
[react/view
|
|
||||||
{:style {:flex-direction :row
|
|
||||||
:justify-content :space-between
|
|
||||||
:padding-vertical 10}}
|
|
||||||
[react/text (i18n/label :t/contract-address)]
|
|
||||||
(when in-progress?
|
|
||||||
[react/view {:flex-direction :row :justify-content :center}
|
|
||||||
[react/view {:height 20}
|
|
||||||
[react/activity-indicator {:width 24 :height 24 :animating true}]]
|
|
||||||
[react/text {:style {:color colors/gray :margin-left 5}}
|
|
||||||
(i18n/label :t/processing)]])]
|
|
||||||
(when-not in-progress?
|
|
||||||
;;tooltip covers button
|
|
||||||
[react/view {:position :absolute :z-index 1000 :right 0 :top 10}
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch [:wallet-legacy.custom-token.ui/contract-address-paste])}
|
|
||||||
[react/text {:style {:color colors/blue}}
|
|
||||||
(i18n/label :t/paste)]]])
|
|
||||||
[quo/text-input
|
|
||||||
{:on-change-text #(debounce-and-save :contract %)
|
|
||||||
:error error
|
|
||||||
:default-value contract
|
|
||||||
:monospace true
|
|
||||||
:multiline true
|
|
||||||
:height 78
|
|
||||||
:auto-focus false
|
|
||||||
:placeholder (i18n/label :t/specify-address)}]]
|
|
||||||
[react/view {:padding-vertical 8}
|
|
||||||
[quo/text-input
|
|
||||||
{:on-change-text #(debounce-and-save :name %)
|
|
||||||
:label (i18n/label :t/name)
|
|
||||||
:default-value name
|
|
||||||
:error error-name
|
|
||||||
:auto-focus false
|
|
||||||
:placeholder (i18n/label :t/name-of-token)}]]
|
|
||||||
[react/view {:padding-vertical 8}
|
|
||||||
[react/view {:style {:flex-direction :row}}
|
|
||||||
[react/view
|
|
||||||
{:flex 1
|
|
||||||
:padding-right 8}
|
|
||||||
[quo/text-input
|
|
||||||
{:on-change-text #(debounce-and-save :symbol %)
|
|
||||||
:label (i18n/label :t/symbol)
|
|
||||||
:error error-symbol
|
|
||||||
:default-value sym
|
|
||||||
:auto-focus false
|
|
||||||
:show-cancel false
|
|
||||||
:placeholder "ABC"}]]
|
|
||||||
[react/view
|
|
||||||
{:flex 1
|
|
||||||
:padding-left 8}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/decimals)
|
|
||||||
:on-change-text #(debounce-and-save :decimals %)
|
|
||||||
:default-value decimals
|
|
||||||
:keyboard-type :number-pad
|
|
||||||
:max-length 2
|
|
||||||
:auto-focus false
|
|
||||||
:show-cancel false
|
|
||||||
:placeholder "18"}]]]]
|
|
||||||
#_[quo/text-input
|
|
||||||
{:label (i18n/label :t/balance)
|
|
||||||
:default-value (when (and balance decimals)
|
|
||||||
(wallet.utils/format-amount balance decimals))
|
|
||||||
:editable false
|
|
||||||
:placeholder (i18n/label :t/no-tokens-found)}]]
|
|
||||||
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:right
|
|
||||||
[quo/button
|
|
||||||
{:type :secondary
|
|
||||||
:after :main-icon/next
|
|
||||||
:disabled (boolean
|
|
||||||
(or in-progress?
|
|
||||||
error
|
|
||||||
error-name
|
|
||||||
error-symbol
|
|
||||||
(string/blank? contract)
|
|
||||||
(string/blank? name)
|
|
||||||
(string/blank? sym)
|
|
||||||
(string/blank? decimals)))
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.custom-token.ui/add-pressed])}
|
|
||||||
(i18n/label :t/add)]}]])))
|
|
||||||
|
|
||||||
(defview custom-token-details
|
|
||||||
[]
|
|
||||||
(letsubs [{:keys [address name decimals custom?] :as token}
|
|
||||||
[:get-screen-params]]
|
|
||||||
[react/keyboard-avoiding-view
|
|
||||||
{:style {:flex 1}
|
|
||||||
:ignore-offset true}
|
|
||||||
[topbar/topbar {:title name}]
|
|
||||||
[react/scroll-view
|
|
||||||
{:keyboard-should-persist-taps :handled
|
|
||||||
:style {:flex 1}}
|
|
||||||
[react/view {:padding-horizontal 16}
|
|
||||||
[react/view {:padding-vertical 8}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/contract-address)
|
|
||||||
:default-value address
|
|
||||||
:multiline true
|
|
||||||
:height 78
|
|
||||||
:editable false}]]
|
|
||||||
[react/view {:padding-vertical 8}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/name)
|
|
||||||
:default-value name
|
|
||||||
:editable false}]]
|
|
||||||
[react/view {:padding-vertical 8}
|
|
||||||
[react/view {:style {:flex-direction :row}}
|
|
||||||
[react/view
|
|
||||||
{:flex 1
|
|
||||||
:padding-right 8}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/symbol)
|
|
||||||
:editable false
|
|
||||||
:show-cancel false
|
|
||||||
:default-value (:symbol token)}]]
|
|
||||||
[react/view {:flex 1 :padding-left 8}
|
|
||||||
[quo/text-input
|
|
||||||
{:label (i18n/label :t/decimals)
|
|
||||||
:show-cancel false
|
|
||||||
:default-value (str decimals)
|
|
||||||
:editable false}]]]]]
|
|
||||||
[react/view {:height 24}]
|
|
||||||
(when custom?
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :negative
|
|
||||||
:title (i18n/label :t/remove-token)
|
|
||||||
:icon :main-icons/delete
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.custom-token.ui/remove-pressed token
|
|
||||||
true])}])]]))
|
|
|
@ -1,350 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.recipient.views
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon]
|
|
||||||
[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.keyboard-avoid-presentation :as kb-presentation]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.components.search-input.view :as search-input]
|
|
||||||
[legacy.status-im.ui.components.toolbar :as toolbar]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as components]
|
|
||||||
[legacy.status-im.utils.utils :as utils]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.address :as address]
|
|
||||||
[utils.debounce :as debounce]
|
|
||||||
[utils.ens.stateofus :as stateofus]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.string :as utils.string])
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
|
||||||
|
|
||||||
(defn- recipient-topbar
|
|
||||||
[]
|
|
||||||
[topbar/topbar
|
|
||||||
{:navigation {:on-press
|
|
||||||
#(do
|
|
||||||
(re-frame/dispatch [:wallet-legacy/recipient-modal-closed])
|
|
||||||
(re-frame/dispatch [:wallet-legacy/search-recipient-filter-changed nil])
|
|
||||||
(re-frame/dispatch [:navigate-back]))}
|
|
||||||
:modal? true
|
|
||||||
:border-bottom false
|
|
||||||
:title (i18n/label :t/recipient)
|
|
||||||
:right-accessories
|
|
||||||
[{:icon :qr
|
|
||||||
:accessibility-label :scan-contact-code-button
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.send/qr-scanner
|
|
||||||
{:ignore-url true
|
|
||||||
:handler :wallet-legacy.send/qr-scanner-result}])}]}])
|
|
||||||
|
|
||||||
(defonce search-active? (reagent/atom false))
|
|
||||||
|
|
||||||
(defn search-input-wrapper
|
|
||||||
[]
|
|
||||||
(let [search-filter @(re-frame/subscribe [:wallet-legacy/search-recipient-filter])]
|
|
||||||
[react/view
|
|
||||||
{:padding-horizontal 16
|
|
||||||
:padding-vertical 10}
|
|
||||||
[search-input/search-input-old
|
|
||||||
{:search-active? search-active?
|
|
||||||
:search-filter search-filter
|
|
||||||
:on-cancel #(re-frame/dispatch [:wallet-legacy/search-recipient-filter-changed nil])
|
|
||||||
:on-change (fn [text]
|
|
||||||
(re-frame/dispatch [:wallet-legacy/search-recipient-filter-changed text])
|
|
||||||
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
|
||||||
(debounce/debounce-and-dispatch [:contacts/set-new-identity {:input text}]
|
|
||||||
300))}]]))
|
|
||||||
|
|
||||||
(defn section
|
|
||||||
[_ _ _]
|
|
||||||
(let [opened? (reagent/atom false)]
|
|
||||||
(fn [title cnt content]
|
|
||||||
[react/view {:padding-vertical 8}
|
|
||||||
[list.item/list-item
|
|
||||||
{:title title
|
|
||||||
:on-press #(swap! opened? not)
|
|
||||||
:accessory
|
|
||||||
[react/view {:flex-direction :row :align-items :center}
|
|
||||||
(when (pos? cnt)
|
|
||||||
[react/text {:style {:color colors/gray}} cnt])
|
|
||||||
[icons/icon (if @opened? :main-icons/dropdown :main-icons/next)
|
|
||||||
{:container-style {:align-items :center
|
|
||||||
:margin-left 8
|
|
||||||
:justify-content :center}
|
|
||||||
:resize-mode :center
|
|
||||||
:color colors/black}]]}]
|
|
||||||
(when @opened?
|
|
||||||
content)])))
|
|
||||||
|
|
||||||
(defn render-account
|
|
||||||
[account]
|
|
||||||
[list.item/list-item
|
|
||||||
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
|
||||||
:title (:name account)
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.send/set-recipient (:address account)])
|
|
||||||
:subtitle [quo/text
|
|
||||||
{:monospace true
|
|
||||||
:color :secondary}
|
|
||||||
(utils/get-shortened-checksum-address (:address account))]}])
|
|
||||||
|
|
||||||
(def scroll-view-ref (atom nil))
|
|
||||||
|
|
||||||
(defn contacts-list-item
|
|
||||||
[{:keys [name] :as contact}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (:primary-name contact)
|
|
||||||
:subtitle (:secondary-name contact)
|
|
||||||
:on-press #(do
|
|
||||||
(some-> ^js @scroll-view-ref
|
|
||||||
(.scrollTo #js {:x 0 :animated true}))
|
|
||||||
(re-frame/dispatch [:wallet-legacy.recipient/address-changed name]))
|
|
||||||
:icon [chat-icon/contact-icon-contacts-tab contact]}])
|
|
||||||
|
|
||||||
(defn empty-items
|
|
||||||
[icon title]
|
|
||||||
[react/view {:height 94 :align-items :center :justify-content :center}
|
|
||||||
[icons/icon icon
|
|
||||||
{:color colors/gray}]
|
|
||||||
[react/text {:style {:color colors/gray :margin-top 8}}
|
|
||||||
title]])
|
|
||||||
|
|
||||||
(views/defview accounts-section
|
|
||||||
[]
|
|
||||||
(views/letsubs [accounts [:accounts-for-recipient]]
|
|
||||||
(let [cnt (count accounts)]
|
|
||||||
[section
|
|
||||||
(i18n/label :t/my-accounts)
|
|
||||||
cnt
|
|
||||||
(if (> cnt 0)
|
|
||||||
[react/view
|
|
||||||
(for [account accounts]
|
|
||||||
[render-account account])]
|
|
||||||
[empty-items :main-icons/address (i18n/label :t/my-accounts-empty)])])))
|
|
||||||
|
|
||||||
(defn render-recent
|
|
||||||
[{:keys [from to type amount-text currency-text]}]
|
|
||||||
(let [inbound? (= type :inbound)
|
|
||||||
address (if inbound? from to)]
|
|
||||||
[list.item/list-item
|
|
||||||
{:title [quo/text {:monospace true}
|
|
||||||
(utils/get-shortened-checksum-address address)]
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.recipient/address-changed address])
|
|
||||||
:size :small
|
|
||||||
:accessory [react/text
|
|
||||||
{:style {:flex-shrink 1
|
|
||||||
:color colors/gray}}
|
|
||||||
(str (if inbound? "↓ " "↑ ") amount-text " " currency-text)]}]))
|
|
||||||
|
|
||||||
(defn recent-section
|
|
||||||
[]
|
|
||||||
(let [{:keys [from]} @(re-frame/subscribe [:wallet-legacy/prepare-transaction])
|
|
||||||
txs @(re-frame/subscribe [:wallet-legacy/recipient-recent-txs (:address from)])
|
|
||||||
cnt (count txs)]
|
|
||||||
[section
|
|
||||||
(i18n/label :t/recent)
|
|
||||||
cnt
|
|
||||||
(if (> cnt 0)
|
|
||||||
[react/view
|
|
||||||
(for [tx txs]
|
|
||||||
[render-recent tx])]
|
|
||||||
[empty-items :main-icons/history (i18n/label :t/recent-empty)])]))
|
|
||||||
|
|
||||||
(defn render-fav
|
|
||||||
[{:keys [address name]}]
|
|
||||||
(let [noname? (string/blank? name)
|
|
||||||
short-address (utils/get-shortened-checksum-address address)]
|
|
||||||
[list.item/list-item
|
|
||||||
{:icon [chat-icon/custom-icon-view-list
|
|
||||||
(if noname? " 2" name)
|
|
||||||
(rand-nth colors/chat-colors)]
|
|
||||||
:title (if noname?
|
|
||||||
[quo/text {:monospace true}
|
|
||||||
short-address]
|
|
||||||
name)
|
|
||||||
:subtitle (when-not noname?
|
|
||||||
[quo/text
|
|
||||||
{:monospace true
|
|
||||||
:color :secondary}
|
|
||||||
short-address])
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.send/set-recipient address])
|
|
||||||
:size (when noname? :small)}]))
|
|
||||||
|
|
||||||
(views/defview fav-section
|
|
||||||
[]
|
|
||||||
(views/letsubs [favourites [:wallet-legacy/favourites-filtered]]
|
|
||||||
(let [cnt (count favourites)]
|
|
||||||
[section
|
|
||||||
(i18n/label :t/favourites)
|
|
||||||
cnt
|
|
||||||
[react/view
|
|
||||||
;;TODO implement later
|
|
||||||
#_[list/list-item
|
|
||||||
{:title "Add favourite"
|
|
||||||
:icon :main-icons/add
|
|
||||||
:theme :accent}]
|
|
||||||
(if (> cnt 0)
|
|
||||||
[react/view
|
|
||||||
(for [data favourites]
|
|
||||||
[render-fav data])]
|
|
||||||
[empty-items :main-icons/favourite (i18n/label :t/favourites-empty)])]])))
|
|
||||||
|
|
||||||
(views/defview contacts-section
|
|
||||||
[]
|
|
||||||
(views/letsubs [contacts [:contacts/active-with-ens-names]]
|
|
||||||
(let [cnt (count contacts)]
|
|
||||||
[section
|
|
||||||
(i18n/label :t/contacts)
|
|
||||||
cnt
|
|
||||||
(if (> cnt 0)
|
|
||||||
[react/view
|
|
||||||
(for [contact contacts]
|
|
||||||
[contacts-list-item contact])]
|
|
||||||
[empty-items :main-icons/username (i18n/label :t/contacts-empty)])])))
|
|
||||||
|
|
||||||
(views/defview search-results
|
|
||||||
[]
|
|
||||||
(views/letsubs [contacts [:contacts/active-with-ens-names]
|
|
||||||
favourites [:wallet-legacy/favourites-filtered]
|
|
||||||
accounts [:accounts-for-recipient]]
|
|
||||||
[react/view
|
|
||||||
(for [account accounts]
|
|
||||||
[render-account account])
|
|
||||||
(for [data favourites]
|
|
||||||
[render-fav data])
|
|
||||||
(for [contact contacts]
|
|
||||||
[contacts-list-item contact])]))
|
|
||||||
|
|
||||||
(defn accordion
|
|
||||||
[search-filter]
|
|
||||||
(if (not (string/blank? search-filter))
|
|
||||||
[search-results]
|
|
||||||
[react/view
|
|
||||||
[components/separator]
|
|
||||||
[accounts-section]
|
|
||||||
[components/separator]
|
|
||||||
[recent-section]
|
|
||||||
[components/separator]
|
|
||||||
[fav-section]
|
|
||||||
[components/separator]
|
|
||||||
[contacts-section]
|
|
||||||
[components/separator]]))
|
|
||||||
|
|
||||||
(views/defview new-favourite
|
|
||||||
[]
|
|
||||||
(views/letsubs [{:keys [resolved-address]} [:wallet-legacy/recipient]
|
|
||||||
fav-name (atom "")]
|
|
||||||
[kb-presentation/keyboard-avoiding-view {:style {:flex 1}}
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[react/scroll-view {:style {:flex 1}}
|
|
||||||
[react/view {:padding-horizontal 16}
|
|
||||||
[react/view
|
|
||||||
{:flex-direction :row
|
|
||||||
:justify-content :space-between
|
|
||||||
:align-items :center
|
|
||||||
:height 40
|
|
||||||
:margin-vertical 8}
|
|
||||||
[quo/text (i18n/label :t/address-or-ens-name)]]
|
|
||||||
[quo/text-input
|
|
||||||
{:multiline true
|
|
||||||
:default-value resolved-address
|
|
||||||
:height 70
|
|
||||||
:editable false
|
|
||||||
:accessibility-label :fav-address}]]
|
|
||||||
[react/view {:height 16}]
|
|
||||||
[quo/list-header (i18n/label :t/name-optional)]
|
|
||||||
[react/view {:padding-horizontal 16}
|
|
||||||
[quo/text-input
|
|
||||||
{:show-cancel false
|
|
||||||
:accessibility-label :fav-name
|
|
||||||
:on-change-text #(reset! fav-name %)}]]]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:center
|
|
||||||
[quo/button
|
|
||||||
{:accessibility-label :add-fav
|
|
||||||
:type :secondary
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy/add-favourite resolved-address
|
|
||||||
@fav-name])}
|
|
||||||
(i18n/label :t/add)]}]]]))
|
|
||||||
|
|
||||||
(views/defview recipient
|
|
||||||
[]
|
|
||||||
(views/letsubs [{:keys [address resolved-address searching]} [:wallet-legacy/recipient]
|
|
||||||
search-filter [:wallet-legacy/search-recipient-filter]]
|
|
||||||
(let [disabled? (or searching (not resolved-address))]
|
|
||||||
[kb-presentation/keyboard-avoiding-view
|
|
||||||
{:style {:flex 1}
|
|
||||||
:ignore-offset true}
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[recipient-topbar]
|
|
||||||
[search-input-wrapper]
|
|
||||||
[react/scroll-view
|
|
||||||
{:style {:flex 1}
|
|
||||||
:keyboard-should-persist-taps :handled
|
|
||||||
:ref #(reset! scroll-view-ref %)}
|
|
||||||
[react/view
|
|
||||||
[components/separator]
|
|
||||||
[react/view {:padding-horizontal 16 :margin-bottom 16}
|
|
||||||
[react/view
|
|
||||||
{:flex-direction :row
|
|
||||||
:justify-content :space-between
|
|
||||||
:align-items :center
|
|
||||||
:height 40
|
|
||||||
:margin-vertical 8}
|
|
||||||
[quo/text (i18n/label :t/address-or-ens-name)]
|
|
||||||
[quo/button
|
|
||||||
{:type :secondary
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.recipient/address-paste-pressed])}
|
|
||||||
(i18n/label :t/paste)]]
|
|
||||||
[quo/text-input
|
|
||||||
{:multiline true
|
|
||||||
:default-value address
|
|
||||||
:height 70
|
|
||||||
:placeholder (i18n/label :t/recipient-code-placeholder)
|
|
||||||
:text-align-vertical :top
|
|
||||||
:on-change-text #(do
|
|
||||||
(re-frame/dispatch [:set-in [:wallet-legacy/recipient :searching]
|
|
||||||
:searching])
|
|
||||||
(debounce/debounce-and-dispatch
|
|
||||||
[:wallet-legacy.recipient/address-changed
|
|
||||||
(utils.string/safe-trim %)]
|
|
||||||
600))
|
|
||||||
:accessibility-label :recipient-address-input}]]
|
|
||||||
[react/view {:align-items :center :height 30 :padding-bottom 8}
|
|
||||||
(if searching
|
|
||||||
[react/small-loading-indicator]
|
|
||||||
(when resolved-address
|
|
||||||
[quo/text
|
|
||||||
{:style {:margin-horizontal 16}
|
|
||||||
:size :small
|
|
||||||
:align :center
|
|
||||||
:color :secondary}
|
|
||||||
(when-not (address/address? address)
|
|
||||||
(str (stateofus/username-with-domain address) " • "))
|
|
||||||
[quo/text
|
|
||||||
{:monospace true
|
|
||||||
:size :inherit
|
|
||||||
:color :inherit}
|
|
||||||
(utils/get-shortened-address resolved-address)]]))]
|
|
||||||
[accordion search-filter]]]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:left
|
|
||||||
[quo/button
|
|
||||||
{:accessibility-label :participant-add-to-favs
|
|
||||||
:type :secondary
|
|
||||||
:disabled disabled?
|
|
||||||
:on-press #(re-frame/dispatch [:open-modal :new-favourite])}
|
|
||||||
(i18n/label :t/add-to-favourites)]
|
|
||||||
:right
|
|
||||||
[quo/button
|
|
||||||
{:accessibility-label :participant-done
|
|
||||||
:type :secondary
|
|
||||||
:after :main-icons/next
|
|
||||||
:disabled disabled?
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.send/set-recipient
|
|
||||||
resolved-address])}
|
|
||||||
(i18n/label :t/done)]}]]])))
|
|
|
@ -1,42 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.request.views
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.copyable-text :as copyable-text]
|
|
||||||
[legacy.status-im.ui.components.core :as quo]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.common.qr-codes.view :as qr-codes]
|
|
||||||
[utils.ethereum.eip.eip55 :as eip55]
|
|
||||||
[utils.ethereum.eip.eip681 :as eip681]
|
|
||||||
[utils.i18n :as i18n])
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
|
||||||
|
|
||||||
(views/defview share-address
|
|
||||||
[]
|
|
||||||
(views/letsubs [{:keys [address]} [:popover/popover]
|
|
||||||
chain-id [:chain-id]
|
|
||||||
width (reagent/atom nil)]
|
|
||||||
[react/view {:on-layout #(reset! width (-> ^js % .-nativeEvent .-layout .-width))}
|
|
||||||
[react/view {:style {:padding-top 16 :padding-horizontal 16}}
|
|
||||||
(when @width
|
|
||||||
[qr-codes/qr-code
|
|
||||||
{:url (eip681/generate-uri address {:chain-id chain-id})
|
|
||||||
:size (- @width 32)}])
|
|
||||||
[copyable-text/copyable-text-view
|
|
||||||
{:label :t/ethereum-address
|
|
||||||
:container-style {:margin-top 12 :margin-bottom 4}
|
|
||||||
:copied-text (eip55/address->checksum address)}
|
|
||||||
[quo/text
|
|
||||||
{:number-of-lines 1
|
|
||||||
:ellipsize-mode :middle
|
|
||||||
:accessibility-label :address-text
|
|
||||||
:monospace true}
|
|
||||||
(eip55/address->checksum address)]]]
|
|
||||||
[react/view
|
|
||||||
{:padding-top 12
|
|
||||||
:padding-horizontal 16
|
|
||||||
:padding-bottom 16}
|
|
||||||
[quo/button
|
|
||||||
{:on-press #(re-frame/dispatch [:wallet-legacy.accounts/share address])
|
|
||||||
:accessibility-label :share-address-button}
|
|
||||||
(i18n/label :t/share-address)]]]))
|
|
|
@ -1,53 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.send.sheets
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views])
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.list.views :as list]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.screens.wallet.accounts.common :as common]
|
|
||||||
[re-frame.core :as re-frame]))
|
|
||||||
|
|
||||||
(defn asset
|
|
||||||
[currency token]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch [:wallet-legacy.send/set-symbol (:symbol token)])}
|
|
||||||
[common/render-asset token nil nil (:code currency)]])
|
|
||||||
|
|
||||||
(views/defview assets
|
|
||||||
[address]
|
|
||||||
(views/letsubs [{:keys [tokens]} [:wallet-legacy/visible-assets-with-values address]
|
|
||||||
currency [:wallet-legacy/currency]]
|
|
||||||
[react/view
|
|
||||||
{:style {:height 300}}
|
|
||||||
[list/flat-list
|
|
||||||
{:data tokens
|
|
||||||
:key-fn :symbol
|
|
||||||
:render-fn (partial asset currency)}]]))
|
|
||||||
|
|
||||||
(defn render-account
|
|
||||||
[account _ _ {:keys [field event]}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
|
||||||
:title (:name account)
|
|
||||||
:on-press #(re-frame/dispatch [event field account])}])
|
|
||||||
|
|
||||||
(views/defview accounts-list
|
|
||||||
[field event]
|
|
||||||
(views/letsubs [accounts [:multiaccount/visible-accounts]
|
|
||||||
accounts-whithout-watch [:visible-accounts-without-watch-only]]
|
|
||||||
[list/flat-list
|
|
||||||
{:data (if (= :to field) accounts accounts-whithout-watch)
|
|
||||||
:key-fn :address
|
|
||||||
:render-data {:field field
|
|
||||||
:event event}
|
|
||||||
:render-fn render-account}]))
|
|
||||||
|
|
||||||
(defn show-accounts-list
|
|
||||||
[]
|
|
||||||
(re-frame/dispatch [:bottom-sheet/hide-old])
|
|
||||||
(js/setTimeout #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content (fn [] [accounts-list :to
|
|
||||||
:wallet-legacy.send/set-field])
|
|
||||||
:content-height 300}])
|
|
||||||
400))
|
|
|
@ -1,34 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.send.styles
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]))
|
|
||||||
|
|
||||||
(defn sheet
|
|
||||||
[]
|
|
||||||
{:flex 1})
|
|
||||||
|
|
||||||
(defn acc-sheet
|
|
||||||
[]
|
|
||||||
{:background-color colors/white
|
|
||||||
:border-top-right-radius 16
|
|
||||||
:border-top-left-radius 16
|
|
||||||
:padding-bottom 60})
|
|
||||||
|
|
||||||
(defn header
|
|
||||||
[small-screen?]
|
|
||||||
{:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :space-between
|
|
||||||
:padding-top (when-not small-screen? 16)
|
|
||||||
:padding-left 16})
|
|
||||||
|
|
||||||
(defn set-max-button
|
|
||||||
[]
|
|
||||||
{:height 35
|
|
||||||
:border-radius 40
|
|
||||||
:background-color colors/blue-light
|
|
||||||
:margin-horizontal 12
|
|
||||||
:align-self :flex-start
|
|
||||||
:margin-bottom 12
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center
|
|
||||||
:padding-horizontal 12})
|
|
|
@ -1,271 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.send.views
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views])
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.core :as components.core]
|
|
||||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
|
||||||
[legacy.status-im.ui.components.keyboard-avoid-presentation :as kb-presentation]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.components.toolbar :as toolbar]
|
|
||||||
[legacy.status-im.ui.components.tooltip.views :as tooltip]
|
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as components]
|
|
||||||
[legacy.status-im.ui.screens.wallet.send.sheets :as sheets]
|
|
||||||
[legacy.status-im.ui.screens.wallet.send.styles :as styles]
|
|
||||||
[legacy.status-im.utils.utils :as utils]
|
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[quo.core :as quo]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.contexts.profile.utils :as profile.utils]
|
|
||||||
[utils.address :as address]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.money :as money]))
|
|
||||||
|
|
||||||
(defn header
|
|
||||||
[{:keys [label small-screen?]}]
|
|
||||||
[react/view (styles/header small-screen?)
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[react/text {:style (merge {:typography :title-bold} (when small-screen? {:font-size 15}))}
|
|
||||||
(i18n/label (or label :t/send-transaction))]]])
|
|
||||||
|
|
||||||
(defn asset-selector
|
|
||||||
[{:keys [request? token from]} window-width]
|
|
||||||
(let [{:keys [name icon color]} token]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press (when-not request?
|
|
||||||
#(do
|
|
||||||
(re-frame/dispatch [:dismiss-keyboard])
|
|
||||||
(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content (fn [] [sheets/assets (:address from)])
|
|
||||||
:content-height 300}])))}
|
|
||||||
[react/view
|
|
||||||
{:style {:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:margin-left 16}
|
|
||||||
:accessibility-label :choose-asset-button}
|
|
||||||
(if icon
|
|
||||||
[components/token-icon
|
|
||||||
(assoc icon
|
|
||||||
:style {:background-color colors/gray-lighter
|
|
||||||
:border-radius 50}
|
|
||||||
:image-style {:width 32 :height 32})]
|
|
||||||
[chat-icon/custom-icon-view-list name color 32])
|
|
||||||
[react/text
|
|
||||||
{:style {:margin-left 8
|
|
||||||
:max-width (/ window-width 4)}
|
|
||||||
:number-of-lines 2}
|
|
||||||
(wallet.utils/display-symbol token)]
|
|
||||||
(when-not request?
|
|
||||||
[icons/icon :main-icons/dropdown {:color colors/gray}])]]))
|
|
||||||
|
|
||||||
(defn render-account
|
|
||||||
[account {:keys [amount decimals] :as token} event]
|
|
||||||
[list.item/list-item
|
|
||||||
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
|
||||||
:title (:name account)
|
|
||||||
:subtitle (when token
|
|
||||||
(str (wallet.utils/format-amount amount decimals)
|
|
||||||
" "
|
|
||||||
(wallet.utils/display-symbol token)))
|
|
||||||
:chevron true
|
|
||||||
:on-press #(do
|
|
||||||
(re-frame/dispatch [:dismiss-keyboard])
|
|
||||||
(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content (fn [] [sheets/accounts-list :from event])
|
|
||||||
:content-height 300}]))}])
|
|
||||||
|
|
||||||
(defn render-contact
|
|
||||||
[{:keys [address] :as contact} from-chat?]
|
|
||||||
(if from-chat?
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (profile.utils/displayed-name contact)
|
|
||||||
:subtitle [components.core/text
|
|
||||||
{:monospace true
|
|
||||||
:color :secondary}
|
|
||||||
(utils/get-shortened-checksum-address address)]
|
|
||||||
:icon [chat-icon/contact-icon-contacts-tab contact]}]
|
|
||||||
[list.item/list-item
|
|
||||||
(merge {:title (if-not contact
|
|
||||||
(i18n/label :t/wallet-choose-recipient)
|
|
||||||
[components.core/text
|
|
||||||
{:size :large
|
|
||||||
:monospace true}
|
|
||||||
(utils/get-shortened-checksum-address
|
|
||||||
(if (string? contact) contact address))])
|
|
||||||
:accessibility-label :choose-recipient-button
|
|
||||||
:on-press #(do
|
|
||||||
(re-frame/dispatch [:dismiss-keyboard])
|
|
||||||
(re-frame/dispatch
|
|
||||||
[:wallet-legacy.send/navigate-to-recipient-code]))
|
|
||||||
:chevron true}
|
|
||||||
(when-not contact
|
|
||||||
{:icon :main-icons/add
|
|
||||||
:theme :accent}))]))
|
|
||||||
|
|
||||||
(defn set-max
|
|
||||||
[token]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press
|
|
||||||
#(when token
|
|
||||||
(re-frame/dispatch [:wallet-legacy.send/set-max-amount token]))}
|
|
||||||
[react/view {:style (styles/set-max-button)}
|
|
||||||
[react/text {:style {:color colors/blue}} (i18n/label :t/set-max)]]])
|
|
||||||
|
|
||||||
(defn fiat-value
|
|
||||||
[amount {sym :symbol} prices wallet-currency]
|
|
||||||
(when-let [price (get-in prices [(keyword sym) (keyword (:code wallet-currency)) :price])]
|
|
||||||
(let [norm-amount (js/parseFloat (money/normalize amount))
|
|
||||||
amount (if (js/isNaN norm-amount) 0 norm-amount)]
|
|
||||||
[react/text
|
|
||||||
{:style {:color colors/gray
|
|
||||||
:margin-left 16
|
|
||||||
:margin-bottom 8
|
|
||||||
:font-size 15
|
|
||||||
:line-height 22}}
|
|
||||||
(str (i18n/format-currency (* amount price) (:code wallet-currency))
|
|
||||||
" "
|
|
||||||
(:code wallet-currency))])))
|
|
||||||
|
|
||||||
(views/defview request-transaction
|
|
||||||
[_]
|
|
||||||
(views/letsubs [{:keys [amount-error amount-text from token sign-enabled?] :as tx}
|
|
||||||
[:wallet-legacy.request/prepare-transaction-with-balance]
|
|
||||||
window-width [:dimensions/window-width]
|
|
||||||
prices [:prices]
|
|
||||||
wallet-currency [:wallet-legacy/currency]]
|
|
||||||
[kb-presentation/keyboard-avoiding-view {:style {:flex 1}}
|
|
||||||
[:<>
|
|
||||||
[react/scroll-view
|
|
||||||
{:style {:flex 1}
|
|
||||||
:keyboard-should-persist-taps :handled}
|
|
||||||
[react/view {:style (styles/sheet)}
|
|
||||||
[react/view
|
|
||||||
{:flex-direction :row
|
|
||||||
:padding-horizontal 24
|
|
||||||
:align-items :center
|
|
||||||
:margin-vertical 16}
|
|
||||||
[react/text-input
|
|
||||||
{:style {:font-size 38
|
|
||||||
:color (if amount-error colors/red colors/black)
|
|
||||||
:flex-shrink 1}
|
|
||||||
:keyboard-type :decimal-pad
|
|
||||||
:auto-capitalize :words
|
|
||||||
:accessibility-label :amount-input
|
|
||||||
:default-value amount-text
|
|
||||||
:auto-focus true
|
|
||||||
:on-change-text #(re-frame/dispatch [:wallet-legacy.request/set-amount-text %])
|
|
||||||
:placeholder "0.0 "}]
|
|
||||||
[asset-selector tx window-width]
|
|
||||||
(when amount-error
|
|
||||||
[tooltip/tooltip amount-error
|
|
||||||
{:bottom-value 2
|
|
||||||
:font-size 12}])]
|
|
||||||
[fiat-value amount-text token prices wallet-currency]
|
|
||||||
[components/separator]
|
|
||||||
[components.core/list-header
|
|
||||||
(i18n/label :t/to-capitalized)]
|
|
||||||
[react/view {:flex-direction :row :flex 1 :align-items :center}
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[render-account from token :wallet-legacy.request/set-field]]]]]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:right
|
|
||||||
[components.core/button
|
|
||||||
{:type :secondary
|
|
||||||
:after :main-icon/next
|
|
||||||
:accessibility-label :request-transaction-bottom-sheet
|
|
||||||
:disabled (not sign-enabled?)
|
|
||||||
:on-press #(do
|
|
||||||
(re-frame/dispatch
|
|
||||||
[:wallet-legacy.ui/request-transaction-button-clicked tx])
|
|
||||||
(re-frame/dispatch [:navigate-back]))}
|
|
||||||
(i18n/label :t/wallet-request)]}]]]))
|
|
||||||
|
|
||||||
(views/defview prepare-send-transaction
|
|
||||||
[_]
|
|
||||||
(views/letsubs [{:keys [amount-error amount-text
|
|
||||||
request?
|
|
||||||
from token to sign-enabled? from-chat?]
|
|
||||||
:as tx}
|
|
||||||
[:wallet-legacy.send/prepare-transaction-with-balance]
|
|
||||||
prices [:prices]
|
|
||||||
wallet-currency [:wallet-legacy/currency]
|
|
||||||
window-width [:dimensions/window-width]]
|
|
||||||
(let [to-norm (address/normalized-hex (if (string? to) to (:address to)))]
|
|
||||||
[kb-presentation/keyboard-avoiding-view {:style {:flex 1}}
|
|
||||||
[:<>
|
|
||||||
[quo/page-nav
|
|
||||||
{:type :title
|
|
||||||
:text-align :left
|
|
||||||
:title (i18n/label :t/send-transaction)
|
|
||||||
:icon-name :i/arrow-left
|
|
||||||
:on-press (fn []
|
|
||||||
(re-frame/dispatch [:navigate-back])
|
|
||||||
(re-frame/dispatch [:wallet-legacy/cancel-transaction-command]))
|
|
||||||
:accessibility-label :back-button}]
|
|
||||||
[react/scroll-view
|
|
||||||
{:style {:flex 1}
|
|
||||||
:keyboard-should-persist-taps :handled}
|
|
||||||
[react/view {:style (styles/sheet)}
|
|
||||||
[react/view
|
|
||||||
{:flex-direction :row
|
|
||||||
:padding-horizontal 16
|
|
||||||
:align-items :center
|
|
||||||
:margin-top 12
|
|
||||||
:margin-bottom 4}
|
|
||||||
[react/text-input
|
|
||||||
{:style {:font-size 38
|
|
||||||
:max-width (- (* (/ window-width 4) 3) 106)
|
|
||||||
:color (if amount-error colors/red colors/black)}
|
|
||||||
:keyboard-type :decimal-pad
|
|
||||||
:auto-capitalize :words
|
|
||||||
:accessibility-label :amount-input
|
|
||||||
:default-value amount-text
|
|
||||||
:editable (not request?)
|
|
||||||
:auto-focus true
|
|
||||||
:on-change-text #(re-frame/dispatch [:wallet-legacy.send/set-amount-text %])
|
|
||||||
:placeholder "0.0 "}]
|
|
||||||
[asset-selector tx window-width]
|
|
||||||
(when amount-error
|
|
||||||
[tooltip/tooltip
|
|
||||||
(if from
|
|
||||||
amount-error
|
|
||||||
(i18n/label :t/select-account-first))
|
|
||||||
{:bottom-value 2
|
|
||||||
:font-size 12}])]
|
|
||||||
[fiat-value amount-text token prices wallet-currency]
|
|
||||||
(when-not (or request? from-chat?)
|
|
||||||
[set-max token])
|
|
||||||
[components/separator]
|
|
||||||
[components.core/list-header (i18n/label :t/from-capitalized)]
|
|
||||||
[react/view {:flex-direction :row :flex 1 :align-items :center}
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[render-account from token :wallet-legacy.send/set-field]]]
|
|
||||||
[components.core/list-header
|
|
||||||
(i18n/label :t/to-capitalized)]
|
|
||||||
[react/view {:flex-direction :row :flex 1 :align-items :center}
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[render-contact to from-chat?]]]]]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:right
|
|
||||||
[quo/button
|
|
||||||
{:accessibility-label :send-transaction-bottom-sheet
|
|
||||||
:type :secondary
|
|
||||||
:after :main-icon/next
|
|
||||||
:disabled (not sign-enabled?)
|
|
||||||
:on-press #(do
|
|
||||||
(re-frame/dispatch [:navigate-back])
|
|
||||||
(re-frame/dispatch
|
|
||||||
[(cond
|
|
||||||
request?
|
|
||||||
:wallet-legacy.ui/sign-transaction-button-clicked-from-request
|
|
||||||
from-chat?
|
|
||||||
:wallet-legacy.ui/sign-transaction-button-clicked-from-chat
|
|
||||||
:else
|
|
||||||
:wallet-legacy.ui/sign-transaction-button-clicked) tx]))}
|
|
||||||
|
|
||||||
(if (and (not request?) from-chat? (not to-norm))
|
|
||||||
(i18n/label :t/wallet-send)
|
|
||||||
(i18n/label :t/next))]}]]])))
|
|
|
@ -1,125 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.settings.views
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.core :as quo]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.list.views :as list]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.components.search-input.view :as search-input]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as wallet.components]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n])
|
|
||||||
(:require-macros [legacy.status-im.utils.views :refer [defview letsubs]]))
|
|
||||||
|
|
||||||
(defonce search-active? (reagent/atom false))
|
|
||||||
|
|
||||||
(defn toolbar
|
|
||||||
[]
|
|
||||||
[topbar/topbar
|
|
||||||
{:title (i18n/label :t/wallet-assets)
|
|
||||||
:navigation
|
|
||||||
{:on-press #(re-frame/dispatch [:wallet-legacy.settings.ui/navigate-back-pressed])}}])
|
|
||||||
|
|
||||||
(defn hide-sheet-and-dispatch
|
|
||||||
[event]
|
|
||||||
(re-frame/dispatch [:bottom-sheet/hide-old])
|
|
||||||
(re-frame/dispatch event))
|
|
||||||
|
|
||||||
(defn custom-token-actions-view
|
|
||||||
[{:keys [custom?] :as token}]
|
|
||||||
(fn []
|
|
||||||
[react/view
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/token-details)
|
|
||||||
:icon :main-icons/warning
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:navigate-to :wallet-custom-token-details token])}]
|
|
||||||
(when custom?
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :negative
|
|
||||||
:title (i18n/label :t/remove-token)
|
|
||||||
:icon :main-icons/delete
|
|
||||||
:on-press #(hide-sheet-and-dispatch
|
|
||||||
[:wallet-legacy.custom-token.ui/remove-pressed token])}])]))
|
|
||||||
|
|
||||||
(defn render-token
|
|
||||||
[_]
|
|
||||||
(reagent/create-class
|
|
||||||
{:should-component-update
|
|
||||||
(fn [_ [_ old-token] [_ new-token]]
|
|
||||||
(not= (:checked? old-token) (:checked? new-token)))
|
|
||||||
:reagent-render
|
|
||||||
(fn [{sym :symbol
|
|
||||||
title :name
|
|
||||||
icon :icon
|
|
||||||
color :color
|
|
||||||
checked? :checked?
|
|
||||||
:as token}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:active checked?
|
|
||||||
:accessory :checkbox
|
|
||||||
:animated-accessory? false
|
|
||||||
:animated false
|
|
||||||
:icon (if icon
|
|
||||||
[wallet.components/token-icon icon]
|
|
||||||
[chat-icon/custom-icon-view-list title color])
|
|
||||||
:title title
|
|
||||||
:subtitle (name sym)
|
|
||||||
:on-press #(re-frame/dispatch [:wallet-legacy.settings/toggle-visible-token
|
|
||||||
(keyword sym)
|
|
||||||
(not checked?)])
|
|
||||||
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
|
||||||
{:content (custom-token-actions-view token)}])}])}))
|
|
||||||
|
|
||||||
(defn- render-token-wrapper
|
|
||||||
[token]
|
|
||||||
[render-token token])
|
|
||||||
|
|
||||||
(defview manage-assets
|
|
||||||
[]
|
|
||||||
(letsubs [{search-filter :search-filter
|
|
||||||
{custom-tokens true default-tokens nil} :tokens}
|
|
||||||
[:wallet-legacy/filtered-grouped-chain-tokens]]
|
|
||||||
{:component-will-unmount #(do
|
|
||||||
(re-frame/dispatch [:wallet-legacy/search-token-filter-changed nil])
|
|
||||||
(reset! search-active? false))}
|
|
||||||
[react/view {:flex 1 :background-color colors/white}
|
|
||||||
[toolbar]
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[react/view
|
|
||||||
{:padding-horizontal 16
|
|
||||||
:padding-vertical 10}
|
|
||||||
[search-input/search-input-old
|
|
||||||
{:search-active? search-active?
|
|
||||||
:search-filter search-filter
|
|
||||||
:on-cancel #(re-frame/dispatch [:wallet-legacy/search-token-filter-changed nil])
|
|
||||||
:on-focus (fn [search-filter]
|
|
||||||
(when-not search-filter
|
|
||||||
(re-frame/dispatch [:wallet-legacy/search-token-filter-changed ""])))
|
|
||||||
:on-change (fn [text]
|
|
||||||
(re-frame/dispatch [:wallet-legacy/search-token-filter-changed text]))}]]
|
|
||||||
[list/section-list
|
|
||||||
{:header
|
|
||||||
[react/view {:margin-top 16}
|
|
||||||
[list.item/list-item
|
|
||||||
{:theme :accent
|
|
||||||
:title (i18n/label :t/add-custom-token)
|
|
||||||
:icon :main-icons/add
|
|
||||||
:on-press
|
|
||||||
#(re-frame/dispatch [:navigate-to :wallet-add-custom-token])}]]
|
|
||||||
:sections (concat
|
|
||||||
(when (seq custom-tokens)
|
|
||||||
[{:title (i18n/label :t/custom)
|
|
||||||
:data custom-tokens}])
|
|
||||||
[{:title (i18n/label :t/default-assets)
|
|
||||||
:data default-tokens}])
|
|
||||||
:key-fn :address
|
|
||||||
:stickySectionHeadersEnabled false
|
|
||||||
:render-section-header-fn
|
|
||||||
(fn [{:keys [title]}]
|
|
||||||
[quo/list-header title])
|
|
||||||
:render-fn render-token-wrapper}]]]))
|
|
|
@ -1,54 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.signing-phrase.views
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views])
|
|
||||||
(:require
|
|
||||||
[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]
|
|
||||||
[utils.i18n :as i18n]))
|
|
||||||
|
|
||||||
(views/defview signing-phrase
|
|
||||||
[]
|
|
||||||
(views/letsubs [phrase [:signing/phrase]
|
|
||||||
{:keys [wallet-set-up-passed?]} [:profile/profile]]
|
|
||||||
[react/view
|
|
||||||
[react/view {:margin-top 24 :margin-horizontal 24 :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/security {:color colors/blue}]]
|
|
||||||
[react/text {:style {:typography :title-bold :margin-top 16 :margin-bottom 8}}
|
|
||||||
(i18n/label :t/this-is-you-signing)]
|
|
||||||
[react/text {:style {:color colors/gray :text-align :center}}
|
|
||||||
(i18n/label :t/three-words-description)]]
|
|
||||||
[react/view
|
|
||||||
{:margin-vertical 16
|
|
||||||
:height 52
|
|
||||||
:background-color colors/gray-lighter
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center}
|
|
||||||
[react/text phrase]]
|
|
||||||
[react/view
|
|
||||||
{:padding-bottom 8
|
|
||||||
:padding-horizontal 24
|
|
||||||
:align-items :center}
|
|
||||||
[react/text {:style {:color colors/gray :text-align :center}}
|
|
||||||
(i18n/label :t/three-words-description-2)]
|
|
||||||
(when-not wallet-set-up-passed?
|
|
||||||
[react/view {:style {:margin-top 16}}
|
|
||||||
[quo/button {:on-press #(re-frame/dispatch [:hide-popover])}
|
|
||||||
(i18n/label :t/remind-me-later)]])
|
|
||||||
[react/view {:style {:padding-vertical 8}}
|
|
||||||
[quo/button
|
|
||||||
{:on-press #(do
|
|
||||||
(when-not wallet-set-up-passed?
|
|
||||||
(re-frame/dispatch [:profile.settings/update-value
|
|
||||||
:wallet-set-up-passed? true]))
|
|
||||||
(re-frame/dispatch [:hide-popover]))
|
|
||||||
:type :secondary}
|
|
||||||
(i18n/label :t/ok-got-it)]]]]))
|
|
|
@ -1,505 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.swap.views
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ethereum.tokens :as tokens]
|
|
||||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon]
|
|
||||||
[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.keyboard-avoid-presentation :as kb-presentation]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.ui.components.search-input.view :as search-input]
|
|
||||||
[legacy.status-im.ui.components.slider :as slider]
|
|
||||||
[legacy.status-im.ui.components.toolbar :as toolbar]
|
|
||||||
[legacy.status-im.ui.components.topbar :as topbar]
|
|
||||||
[legacy.status-im.ui.screens.wallet.components.views :as wallet.components]
|
|
||||||
[legacy.status-im.wallet.swap.core :as wallet-legacy.swap]
|
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
(defn render-asset
|
|
||||||
[{{:keys
|
|
||||||
[icon decimals amount color value]
|
|
||||||
:as token}
|
|
||||||
:token
|
|
||||||
currency :currency
|
|
||||||
on-press :on-press}]
|
|
||||||
[list.item/list-item
|
|
||||||
{:title [quo/text {:weight :medium}
|
|
||||||
[quo/text {:weight :inherit}
|
|
||||||
(str (if amount
|
|
||||||
(wallet.utils/format-amount amount decimals)
|
|
||||||
"...")
|
|
||||||
" ")]
|
|
||||||
[quo/text
|
|
||||||
{:color :secondary
|
|
||||||
:weight :inherit}
|
|
||||||
(wallet.utils/display-symbol token)]]
|
|
||||||
:on-press on-press
|
|
||||||
:subtitle (str (if value value "...") " " currency)
|
|
||||||
:accessibility-label
|
|
||||||
(str (:symbol token) "-asset-value")
|
|
||||||
:icon (if icon
|
|
||||||
[wallet.components/token-icon icon]
|
|
||||||
[chat-icon/custom-icon-view-list (:name token) color])}])
|
|
||||||
|
|
||||||
(defn asset-selector
|
|
||||||
[]
|
|
||||||
(let [{:keys [address]} (rf/sub [:multiaccount/current-account])
|
|
||||||
{:keys [tokens]} (rf/sub [:wallet-legacy/visible-assets-with-values address])
|
|
||||||
source? (rf/sub [:wallet-legacy/modal-selecting-source-token?])
|
|
||||||
currency (rf/sub [:wallet-legacy/currency])]
|
|
||||||
[:<>
|
|
||||||
[topbar/topbar
|
|
||||||
{:title (if source?
|
|
||||||
(i18n/label :t/select-token-to-swap)
|
|
||||||
(i18n/label :t/select-token-to-receive))
|
|
||||||
:modal? true}]
|
|
||||||
|
|
||||||
[search-input/search-input-old
|
|
||||||
{:search-active? true}]
|
|
||||||
|
|
||||||
[react/scroll-view
|
|
||||||
(for [token tokens]
|
|
||||||
^{:key (:name token)}
|
|
||||||
[render-asset
|
|
||||||
{:token token
|
|
||||||
:on-press #(re-frame/dispatch
|
|
||||||
[(if source?
|
|
||||||
::wallet-legacy.swap/set-from-token
|
|
||||||
::wallet-legacy.swap/set-to-token)
|
|
||||||
(:symbol token)])
|
|
||||||
:currency (:code currency)}])]]))
|
|
||||||
|
|
||||||
(defn pill-button
|
|
||||||
[{:keys [on-press label margin-left]}]
|
|
||||||
[react/touchable-opacity
|
|
||||||
{:on-press on-press
|
|
||||||
:style {:background-color colors/blue-light
|
|
||||||
:padding-horizontal 12
|
|
||||||
:padding-vertical 2
|
|
||||||
:border-radius 24
|
|
||||||
:margin-left (or margin-left 8)}}
|
|
||||||
[quo/text
|
|
||||||
{:color :link
|
|
||||||
:weight :medium} label]])
|
|
||||||
|
|
||||||
(defn token-display
|
|
||||||
"Show token and act as an anchor to open selector."
|
|
||||||
[{:keys [token source?]}]
|
|
||||||
(let [token-icon-source (-> token :icon :source)]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(re-frame/dispatch [::wallet-legacy.swap/open-asset-selector-modal source?])}
|
|
||||||
[react/view
|
|
||||||
{:style {:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:border-width 1
|
|
||||||
:border-color colors/gray-lighter
|
|
||||||
:border-radius 8
|
|
||||||
:margin-left 16
|
|
||||||
:padding-horizontal 8
|
|
||||||
:padding-vertical 2}
|
|
||||||
:accessibility-label
|
|
||||||
:choose-asset-button}
|
|
||||||
[quo/text {:style {:margin-right 8}}
|
|
||||||
(-> token :symbol name)]
|
|
||||||
[react/image
|
|
||||||
{:source (if (fn? token-icon-source)
|
|
||||||
(token-icon-source)
|
|
||||||
token-icon-source)}]]]))
|
|
||||||
|
|
||||||
(defn token-input
|
|
||||||
"Component to get the amount and type of tokens"
|
|
||||||
[{:keys [amount error label token max-from source?]}]
|
|
||||||
(let [window-width (rf/sub [:dimensions/window-width])]
|
|
||||||
[react/view
|
|
||||||
{:style {:justify-content :space-between
|
|
||||||
:flex-direction :row
|
|
||||||
:align-items :center}}
|
|
||||||
[react/view {:flex 2}
|
|
||||||
[react/view
|
|
||||||
{:flex-direction :row
|
|
||||||
:align-items :center}
|
|
||||||
[quo/text label]
|
|
||||||
(when max-from
|
|
||||||
[pill-button
|
|
||||||
{:on-press #()
|
|
||||||
:label "Max 0.043"}])]
|
|
||||||
[react/text-input
|
|
||||||
{:style {:font-size 38
|
|
||||||
:max-width (- (* (/ window-width 4) 3) 106)
|
|
||||||
:color (if error colors/red colors/black)}
|
|
||||||
:keyboard-type :decimal-pad
|
|
||||||
:auto-capitalize :words
|
|
||||||
:accessibility-label :amount-input
|
|
||||||
:default-value amount
|
|
||||||
:editable true
|
|
||||||
:auto-focus true
|
|
||||||
:on-change-text #(re-frame/dispatch [(when source?
|
|
||||||
::wallet-legacy.swap/set-from-token-amount)
|
|
||||||
%])
|
|
||||||
:placeholder "0.0"}]]
|
|
||||||
[token-display
|
|
||||||
{:token token
|
|
||||||
:source? source?}]]))
|
|
||||||
|
|
||||||
(defn separator-with-icon
|
|
||||||
[]
|
|
||||||
[react/view
|
|
||||||
{:margin-vertical 8}
|
|
||||||
[quo/separator]
|
|
||||||
[react/touchable-opacity
|
|
||||||
{:on-press #(re-frame/dispatch [::wallet-legacy.swap/switch-from-token-with-to])}
|
|
||||||
[react/view
|
|
||||||
{:style {:background-color colors/gray-lighter
|
|
||||||
:width 40
|
|
||||||
:height 40
|
|
||||||
:border-radius 40
|
|
||||||
:border-width 4
|
|
||||||
:border-color colors/white
|
|
||||||
:margin-top -20
|
|
||||||
:margin-bottom -20
|
|
||||||
:align-self :center
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center}}
|
|
||||||
[react/image
|
|
||||||
{:source (icons/icon-source :main-icons/change)
|
|
||||||
:style {:tint-color colors/gray
|
|
||||||
:transform [{:rotate "90deg"}]}}]]]])
|
|
||||||
|
|
||||||
(defn floating-card
|
|
||||||
[{:keys [icon title body on-press]}]
|
|
||||||
[react/view
|
|
||||||
{:style {:border-width 1
|
|
||||||
:padding 2 ;; need a padding because border breaks otherwise
|
|
||||||
:border-radius 12
|
|
||||||
:margin-top 12
|
|
||||||
:border-color colors/gray-lighter}}
|
|
||||||
[list.item/list-item
|
|
||||||
{:title title
|
|
||||||
:subtitle body
|
|
||||||
:active-background-enabled
|
|
||||||
false
|
|
||||||
:on-press on-press
|
|
||||||
:theme :main
|
|
||||||
:chevron true
|
|
||||||
:icon [react/view
|
|
||||||
{:style {:background-color colors/blue-light
|
|
||||||
:padding 8
|
|
||||||
:border-radius 4}}
|
|
||||||
(icons/icon icon {:color :dark})]}]])
|
|
||||||
|
|
||||||
(defn card-body-row
|
|
||||||
[k value primary?]
|
|
||||||
[react/view {:flex-direction :row}
|
|
||||||
[quo/text {:color (when-not primary? :secondary)} k]
|
|
||||||
[quo/text
|
|
||||||
{:style {:margin-right 4}
|
|
||||||
:color (when-not primary? :secondary)} ":"]
|
|
||||||
[quo/text
|
|
||||||
{:ellipsize-mode :middle
|
|
||||||
:number-of-lines 1
|
|
||||||
:style {:width "50%"}
|
|
||||||
:color (when-not primary? :secondary)
|
|
||||||
:weight :semi-bold} value]])
|
|
||||||
|
|
||||||
(defn transaction-fee-card
|
|
||||||
[{:keys [gas-amount price-limit tip-limit gas-in-eth gas-in-usd]}]
|
|
||||||
[floating-card
|
|
||||||
{:title (i18n/label :t/transaction-fee)
|
|
||||||
:icon :main-icons/gas
|
|
||||||
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-transaction-fee])
|
|
||||||
:body [react/view
|
|
||||||
[card-body-row (i18n/label :t/gas-amount-limit) gas-amount]
|
|
||||||
[card-body-row (i18n/label :t/per-gas-price-limit) price-limit]
|
|
||||||
[card-body-row (i18n/label :t/per-gas-tip-limit) tip-limit]
|
|
||||||
[card-body-row (i18n/label :t/total-gas)
|
|
||||||
(str gas-in-eth " • $" gas-in-usd)
|
|
||||||
true]]}])
|
|
||||||
|
|
||||||
(defn swap-details-card
|
|
||||||
[{:keys [slippage price-impact]}]
|
|
||||||
[floating-card
|
|
||||||
{:title (i18n/label :t/swap-details)
|
|
||||||
:icon :main-icons/change
|
|
||||||
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-swap-details])
|
|
||||||
:body [react/view
|
|
||||||
[card-body-row (i18n/label :t/slippage) (str slippage " %")]
|
|
||||||
[card-body-row (i18n/label :t/price-impact) (str price-impact " %")]]}])
|
|
||||||
|
|
||||||
(defn nonce-card
|
|
||||||
[{:keys [nonce]}]
|
|
||||||
[floating-card
|
|
||||||
{:title (i18n/label :t/nonce)
|
|
||||||
:icon :main-icons/channel
|
|
||||||
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-nonce])
|
|
||||||
:body [react/view
|
|
||||||
[card-body-row (i18n/label :t/nonce) nonce]]}])
|
|
||||||
|
|
||||||
(defn approve-token-card
|
|
||||||
[{:keys [token contract-address approve-limit]}]
|
|
||||||
[floating-card
|
|
||||||
{:title (i18n/label :t/approve)
|
|
||||||
:icon :main-icons/check
|
|
||||||
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-approve-token])
|
|
||||||
:body [react/view
|
|
||||||
[card-body-row (i18n/label :t/token) token]
|
|
||||||
[card-body-row (i18n/label :t/contract-address) contract-address]
|
|
||||||
[card-body-row (i18n/label :t/approve-limit) approve-limit]]}])
|
|
||||||
|
|
||||||
(defn advanced-input
|
|
||||||
[{:keys [label label-help value on-change after]}]
|
|
||||||
[react/view
|
|
||||||
{:style {:padding-horizontal 16
|
|
||||||
:margin-bottom 16}}
|
|
||||||
[react/view
|
|
||||||
{:style {:flex-direction :row
|
|
||||||
:justify-content :space-between}}
|
|
||||||
[quo/text {} label]
|
|
||||||
label-help]
|
|
||||||
|
|
||||||
[quo/text-input
|
|
||||||
{:default-value (str value)
|
|
||||||
:show-cancel false
|
|
||||||
:style {:margin-top 12
|
|
||||||
:border-radius 8}
|
|
||||||
:after {:component after}
|
|
||||||
:on-change-text on-change}]])
|
|
||||||
|
|
||||||
(defn help-label-kv
|
|
||||||
[{k :key v :value}]
|
|
||||||
[react/view {:style {:flex-direction :row}}
|
|
||||||
[quo/text {:color :secondary} k]
|
|
||||||
[quo/text
|
|
||||||
{:color :secondary
|
|
||||||
:style {:margin-right 4}} ":"]
|
|
||||||
[quo/text {:color :secondary} v]])
|
|
||||||
|
|
||||||
(defn nonce-modal
|
|
||||||
[]
|
|
||||||
(let [last-txn-nonce 22
|
|
||||||
nonce 23]
|
|
||||||
[kb-presentation/keyboard-avoiding-view
|
|
||||||
{:style {:flex 1
|
|
||||||
:margin-top 16}
|
|
||||||
:ignore-offset true}
|
|
||||||
[advanced-input
|
|
||||||
{:label (i18n/label :t/nonce)
|
|
||||||
:label-help [help-label-kv
|
|
||||||
{:key (i18n/label :t/last-transaction)
|
|
||||||
:value last-txn-nonce}]
|
|
||||||
:value nonce
|
|
||||||
:on-change #()
|
|
||||||
:on-save #()}]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:left [quo/button {:type :secondary}
|
|
||||||
(i18n/label :t/cancel)]
|
|
||||||
:right [quo/button {:theme :accent}
|
|
||||||
(i18n/label :t/save)]}]]))
|
|
||||||
|
|
||||||
(defn approve-token-modal
|
|
||||||
[]
|
|
||||||
[quo/text "modal"])
|
|
||||||
|
|
||||||
(defn transaction-fee-modal
|
|
||||||
[]
|
|
||||||
(let [gas-amount-limit 21000
|
|
||||||
gas-amount 21000
|
|
||||||
per-gas-price-limit 7.3
|
|
||||||
current-avg-per-gas-price-limit 7.3
|
|
||||||
per-gas-tip-limit 150
|
|
||||||
current-avg-per-gas-tip-limit 150]
|
|
||||||
[kb-presentation/keyboard-avoiding-view
|
|
||||||
{:style {:flex 1
|
|
||||||
:margin-top 16}
|
|
||||||
:ignore-offset true}
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[advanced-input
|
|
||||||
{:label (i18n/label :t/gas-amount-limit)
|
|
||||||
:label-help [help-label-kv
|
|
||||||
{:key (i18n/label :t/limit)
|
|
||||||
:value gas-amount-limit}]
|
|
||||||
:value gas-amount
|
|
||||||
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
|
|
||||||
:on-change #()
|
|
||||||
:on-save #()}]
|
|
||||||
|
|
||||||
[advanced-input
|
|
||||||
{:label (i18n/label :t/per-gas-price-limit)
|
|
||||||
:label-help [help-label-kv
|
|
||||||
{:key (i18n/label :t/current-average)
|
|
||||||
:value current-avg-per-gas-price-limit}]
|
|
||||||
:value per-gas-price-limit
|
|
||||||
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
|
|
||||||
:on-change #()
|
|
||||||
:on-save #()}]
|
|
||||||
|
|
||||||
[advanced-input
|
|
||||||
{:label (i18n/label :t/per-gas-price-limit)
|
|
||||||
:label-help [help-label-kv
|
|
||||||
{:key (i18n/label :t/current-average)
|
|
||||||
:value current-avg-per-gas-tip-limit}]
|
|
||||||
:value per-gas-tip-limit
|
|
||||||
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
|
|
||||||
:on-change #()
|
|
||||||
:on-save #()}]
|
|
||||||
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (i18n/label :t/maximum-fee)
|
|
||||||
:text-size :base
|
|
||||||
:title-text-weight :regular
|
|
||||||
:accessory :text
|
|
||||||
:accessory-text [quo/text "0.3 ETH"]
|
|
||||||
:container-style {:margin-top 16}}]
|
|
||||||
[quo/text
|
|
||||||
{:color :secondary
|
|
||||||
:style {:padding-horizontal 16}}
|
|
||||||
(i18n/label :t/maximum-fee-desc)]]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:left [quo/button {:type :secondary}
|
|
||||||
(i18n/label :t/cancel)]
|
|
||||||
:right [quo/button {:theme :accent}
|
|
||||||
(i18n/label :t/save)]}]]))
|
|
||||||
|
|
||||||
(defn swap-details-modal
|
|
||||||
[]
|
|
||||||
(let [slippage-limit 20
|
|
||||||
slippage 0.5
|
|
||||||
price-impact 4]
|
|
||||||
[kb-presentation/keyboard-avoiding-view
|
|
||||||
{:style {:flex 1
|
|
||||||
:margin-top 16}
|
|
||||||
:ignore-offset true}
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[advanced-input
|
|
||||||
{:label (str (i18n/label :t/slippage) " %")
|
|
||||||
:label-help [help-label-kv
|
|
||||||
{:key (i18n/label :t/limit)
|
|
||||||
:value (str slippage-limit "%")}]
|
|
||||||
:value slippage
|
|
||||||
:on-change #()
|
|
||||||
:on-save #()}]
|
|
||||||
|
|
||||||
[list.item/list-item
|
|
||||||
{:title (i18n/label :t/price-impact)
|
|
||||||
:text-size :base
|
|
||||||
:title-text-weight :regular
|
|
||||||
:accessory :text
|
|
||||||
:accessory-text (str price-impact "%")
|
|
||||||
:container-style {:margin-top 16}}]
|
|
||||||
[quo/text
|
|
||||||
{:color :secondary
|
|
||||||
:style {:padding-horizontal 16}}
|
|
||||||
(i18n/label :t/price-impact-desc)]]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:left [quo/button {:type :secondary}
|
|
||||||
(i18n/label :t/cancel)]
|
|
||||||
:right [quo/button {:theme :accent}
|
|
||||||
(i18n/label :t/save)]}]]))
|
|
||||||
|
|
||||||
(defn advanced-settings
|
|
||||||
[]
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:padding-horizontal 16}}
|
|
||||||
[react/view {:align-self :flex-start}
|
|
||||||
[pill-button
|
|
||||||
{:label (i18n/label :t/switch-to-simple-interface)
|
|
||||||
:margin-left 0
|
|
||||||
:on-press #(re-frame/dispatch [::wallet-legacy.swap/set-advanced-mode false])}]]
|
|
||||||
[transaction-fee-card
|
|
||||||
{:gas-amount 21000
|
|
||||||
:price-limit 74
|
|
||||||
:tip-limit 21
|
|
||||||
:gas-in-eth 0.0031
|
|
||||||
:gas-in-usd 34.28}]
|
|
||||||
[swap-details-card
|
|
||||||
{:slippage 0.5
|
|
||||||
:price-impact 4}]
|
|
||||||
[approve-token-card
|
|
||||||
{:token "USDC"
|
|
||||||
:contract-address "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2"
|
|
||||||
:approve-limit "unlimited"}]
|
|
||||||
[nonce-card {:nonce 22}]])
|
|
||||||
|
|
||||||
(defn swap
|
|
||||||
[]
|
|
||||||
(let [{:keys [name]}
|
|
||||||
(rf/sub [:multiaccount/current-account])
|
|
||||||
all-tokens (rf/sub [:wallet-legacy/all-tokens])
|
|
||||||
from-symbol (rf/sub [:wallet-legacy/swap-from-token])
|
|
||||||
to-symbol (rf/sub [:wallet-legacy/swap-to-token])
|
|
||||||
advanced-mode? (rf/sub [:wallet-legacy/swap-advanced-mode?])
|
|
||||||
amount "0.02"
|
|
||||||
from-token (tokens/symbol->token all-tokens (or from-symbol :DGX))
|
|
||||||
to-token (tokens/symbol->token all-tokens (or to-symbol :SNT))]
|
|
||||||
|
|
||||||
[kb-presentation/keyboard-avoiding-view
|
|
||||||
{:style (merge
|
|
||||||
{:flex 1})
|
|
||||||
:ignore-offset true}
|
|
||||||
[topbar/topbar
|
|
||||||
{:title name
|
|
||||||
:subtitle (string/upper-case (i18n/label :t/powered-by-paraswap))
|
|
||||||
:modal? true}]
|
|
||||||
|
|
||||||
[react/view
|
|
||||||
(merge {:padding-horizontal 16
|
|
||||||
:margin-vertical 32}
|
|
||||||
(when-not advanced-mode?
|
|
||||||
{:flex 1}))
|
|
||||||
[token-input
|
|
||||||
{:amount amount
|
|
||||||
:error nil
|
|
||||||
:label (i18n/label :t/amount)
|
|
||||||
:token from-token
|
|
||||||
:source? true
|
|
||||||
:max-from 67.28}]
|
|
||||||
|
|
||||||
[separator-with-icon]
|
|
||||||
|
|
||||||
[token-input
|
|
||||||
{:amount "0.01"
|
|
||||||
:error nil
|
|
||||||
:label (i18n/label :t/minimum-received)
|
|
||||||
:source? false
|
|
||||||
:token to-token}]]
|
|
||||||
|
|
||||||
(when-not advanced-mode?
|
|
||||||
[react/view
|
|
||||||
{:style {:flex-direction :row
|
|
||||||
:justify-content :space-between
|
|
||||||
:padding-horizontal 16
|
|
||||||
:align-items :center}}
|
|
||||||
[react/view {:style {:flex-direction :row}}
|
|
||||||
[quo/text {} (i18n/label :t/priority)]
|
|
||||||
[pill-button
|
|
||||||
{:label (i18n/label :t/advanced)
|
|
||||||
:on-press #(re-frame/dispatch [::wallet-legacy.swap/set-advanced-mode true])}]]
|
|
||||||
|
|
||||||
[quo/text {:color :secondary} "0.0034 ETH/ $ 8.09"]])
|
|
||||||
|
|
||||||
(comment
|
|
||||||
(re-frame/dispatch [::wallet-legacy.swap/set-advanced-mode false]))
|
|
||||||
|
|
||||||
(when-not advanced-mode?
|
|
||||||
[react/view {:style {:padding-horizontal 16}}
|
|
||||||
[slider/animated-slider
|
|
||||||
{:minimum-value 0
|
|
||||||
:maximum-value 100
|
|
||||||
:style {:margin-vertical 8}}]])
|
|
||||||
|
|
||||||
(when advanced-mode?
|
|
||||||
[quo/text "here"]
|
|
||||||
[advanced-settings])
|
|
||||||
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:right [quo/button {:theme :accent}
|
|
||||||
(i18n/label :t/swap)]}]]))
|
|
|
@ -1,141 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.transactions.styles
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.utils.styles :as styles]))
|
|
||||||
|
|
||||||
(def forward
|
|
||||||
{:color colors/gray})
|
|
||||||
|
|
||||||
(def empty-text
|
|
||||||
{:text-align :center
|
|
||||||
:color colors/gray
|
|
||||||
:margin-top 22
|
|
||||||
:margin-horizontal 92})
|
|
||||||
|
|
||||||
(styles/def amount-time
|
|
||||||
{:flex-direction :row
|
|
||||||
:justify-content :space-between
|
|
||||||
:padding-right 22
|
|
||||||
:padding-left 17
|
|
||||||
:ios {:padding-top 13}
|
|
||||||
:android {:padding-top 14}})
|
|
||||||
|
|
||||||
(def tx-amount
|
|
||||||
{:flex-grow 1
|
|
||||||
:flex-shrink 1
|
|
||||||
:margin-right 10
|
|
||||||
:font-size 17})
|
|
||||||
|
|
||||||
(def tx-time
|
|
||||||
{:flex-grow 1
|
|
||||||
:font-size 14
|
|
||||||
:text-align :right
|
|
||||||
:color colors/blue})
|
|
||||||
|
|
||||||
(def address-row
|
|
||||||
{:flex-direction :row
|
|
||||||
:padding-right 22
|
|
||||||
:padding-left 17
|
|
||||||
:padding-top 4})
|
|
||||||
|
|
||||||
(def address-label
|
|
||||||
{:margin-right 5
|
|
||||||
:font-size 16
|
|
||||||
:color colors/gray})
|
|
||||||
|
|
||||||
(def address-contact
|
|
||||||
{:margin-right 5
|
|
||||||
:font-size 16})
|
|
||||||
|
|
||||||
(def address-hash
|
|
||||||
{:flex-shrink 1})
|
|
||||||
|
|
||||||
(defn transaction-icon-background
|
|
||||||
[color]
|
|
||||||
{:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:width 40
|
|
||||||
:height 40
|
|
||||||
:border-radius 32
|
|
||||||
:background-color color})
|
|
||||||
|
|
||||||
;; transaction details
|
|
||||||
|
|
||||||
(def details-row
|
|
||||||
{:flex-direction :row
|
|
||||||
:margin-vertical 5})
|
|
||||||
|
|
||||||
(def details-item-label
|
|
||||||
{:flex 1
|
|
||||||
:margin-right 10
|
|
||||||
:color colors/gray})
|
|
||||||
|
|
||||||
(def details-item-value-wrapper
|
|
||||||
{:flex 5})
|
|
||||||
|
|
||||||
(def details-item-value
|
|
||||||
{:font-size 14})
|
|
||||||
|
|
||||||
(def details-item-extra-value
|
|
||||||
{:font-size 14
|
|
||||||
:color colors/gray})
|
|
||||||
|
|
||||||
(def details-header
|
|
||||||
{:margin-horizontal 16
|
|
||||||
:margin-top 10
|
|
||||||
:flex-direction :row})
|
|
||||||
|
|
||||||
(def details-header-icon
|
|
||||||
{:margin-vertical 7})
|
|
||||||
|
|
||||||
(def details-header-infos
|
|
||||||
{:flex 1
|
|
||||||
:flex-direction :column
|
|
||||||
:margin-left 12
|
|
||||||
:margin-vertical 7})
|
|
||||||
|
|
||||||
(def details-header-value
|
|
||||||
{:font-size 16})
|
|
||||||
|
|
||||||
(def details-header-date
|
|
||||||
{:font-size 14
|
|
||||||
:color colors/gray})
|
|
||||||
|
|
||||||
(def details-block
|
|
||||||
{:margin-horizontal 16})
|
|
||||||
|
|
||||||
(def progress-bar
|
|
||||||
{:flex-direction :row
|
|
||||||
:margin-vertical 10
|
|
||||||
:height 2})
|
|
||||||
|
|
||||||
(defn progress-bar-done
|
|
||||||
[done failed?]
|
|
||||||
{:flex done
|
|
||||||
:background-color (if failed?
|
|
||||||
colors/red
|
|
||||||
colors/blue)})
|
|
||||||
|
|
||||||
(defn progress-bar-todo
|
|
||||||
[todo failed?]
|
|
||||||
{:flex todo
|
|
||||||
:background-color (if failed?
|
|
||||||
colors/red
|
|
||||||
colors/blue)
|
|
||||||
:opacity 0.30})
|
|
||||||
|
|
||||||
(def details-confirmations-count
|
|
||||||
{:margin-vertical 2})
|
|
||||||
|
|
||||||
(def details-failed
|
|
||||||
{:color colors/red
|
|
||||||
:margin-vertical 2})
|
|
||||||
|
|
||||||
(def details-confirmations-helper-text
|
|
||||||
{:color colors/gray
|
|
||||||
:margin-vertical 2})
|
|
||||||
|
|
||||||
(def details-separator
|
|
||||||
{:background-color colors/black-transparent
|
|
||||||
:height 1
|
|
||||||
:margin-vertical 10})
|
|
|
@ -1,304 +0,0 @@
|
||||||
(ns legacy.status-im.ui.screens.wallet.transactions.views
|
|
||||||
(:require
|
|
||||||
[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.list-selection :as list-selection]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.list.views :as list]
|
|
||||||
[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.wallet.transactions.styles :as styles]
|
|
||||||
[legacy.status-im.utils.utils :as utils]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[utils.i18n :as i18n])
|
|
||||||
(:require-macros [legacy.status-im.utils.views :refer [defview letsubs]]))
|
|
||||||
|
|
||||||
(defn- transaction-icon
|
|
||||||
[icon-key background-color color]
|
|
||||||
{:icon icon-key
|
|
||||||
:icon-color color
|
|
||||||
:icon-bg-color background-color})
|
|
||||||
|
|
||||||
(defn- transaction-type->icon
|
|
||||||
[k]
|
|
||||||
(case k
|
|
||||||
:inbound (transaction-icon :main-icons/arrow-left
|
|
||||||
colors/green-transparent-10
|
|
||||||
colors/green)
|
|
||||||
:outbound (transaction-icon :main-icons/arrow-right
|
|
||||||
colors/blue-transparent-10
|
|
||||||
colors/blue)
|
|
||||||
:failed (transaction-icon :main-icons/warning
|
|
||||||
colors/black-transparent
|
|
||||||
colors/red)
|
|
||||||
:pending (transaction-icon :main-icons/arrow-right
|
|
||||||
colors/black-transparent
|
|
||||||
colors/gray)
|
|
||||||
(throw (js/Error. (str "Unknown transaction type: " k)))))
|
|
||||||
|
|
||||||
(defn render-transaction
|
|
||||||
[{:keys [label contact address contact-accessibility-label
|
|
||||||
currency-text amount-text
|
|
||||||
time-formatted on-touch-fn type]
|
|
||||||
:as transaction}
|
|
||||||
_ _ {:keys [keycard-account?]}]
|
|
||||||
[:<>
|
|
||||||
[list.item/list-item
|
|
||||||
(merge
|
|
||||||
{:on-press on-touch-fn
|
|
||||||
:accessibility-label :transaction-item
|
|
||||||
:title (str amount-text " " currency-text)
|
|
||||||
:subtitle (str label
|
|
||||||
" "
|
|
||||||
(when contact
|
|
||||||
[react/text
|
|
||||||
{:style styles/address-contact
|
|
||||||
:accessibility-label contact-accessibility-label}
|
|
||||||
contact])
|
|
||||||
" "
|
|
||||||
(utils/get-shortened-address address)
|
|
||||||
" "
|
|
||||||
(i18n/label :t/at)
|
|
||||||
" "
|
|
||||||
time-formatted)
|
|
||||||
:chevron true}
|
|
||||||
(when type (transaction-type->icon (keyword type))))]
|
|
||||||
;; Disabling for now as we have added nonce which is more reliable, until we address the ux
|
|
||||||
;; issues
|
|
||||||
(when (and false
|
|
||||||
(not keycard-account?)
|
|
||||||
(= type :pending))
|
|
||||||
[react/view {:flex-direction :row :padding 16 :justify-content :space-between}
|
|
||||||
[quo/button
|
|
||||||
{:on-press #(re-frame/dispatch [:signing.ui/increase-gas-pressed (:hash transaction)])}
|
|
||||||
(i18n/label :t/increase-gas)]
|
|
||||||
[quo/button
|
|
||||||
{:on-press #(re-frame/dispatch [:signing.ui/cancel-transaction-pressed (:hash transaction)])}
|
|
||||||
(i18n/label :t/cancel)]])])
|
|
||||||
|
|
||||||
(defn chain-explorer-link
|
|
||||||
[address]
|
|
||||||
(let [link @(re-frame/subscribe [:wallet-legacy/chain-explorer-link address])]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(when link
|
|
||||||
(.openURL ^js react/linking link))}
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:padding-horizontal 14
|
|
||||||
:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:background-color colors/blue-light
|
|
||||||
:height 52}}
|
|
||||||
[icons/tiny-icon
|
|
||||||
:tiny-icons/tiny-external
|
|
||||||
{:color colors/blue
|
|
||||||
:container-style {:margin-right 5}}]
|
|
||||||
[react/text
|
|
||||||
{:style {:color colors/blue}}
|
|
||||||
(i18n/label :t/check-on-block-explorer)]]]))
|
|
||||||
|
|
||||||
(defn custom-node
|
|
||||||
[]
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:padding-horizontal 14
|
|
||||||
:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:background-color (colors/get-color :warning-02)
|
|
||||||
:height 52}}
|
|
||||||
[react/text
|
|
||||||
{:style {:color (colors/get-color :warning-01)}}
|
|
||||||
(i18n/label :t/custom-node)]])
|
|
||||||
|
|
||||||
(defn non-archival-node
|
|
||||||
[]
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:padding-horizontal 14
|
|
||||||
:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:background-color (colors/get-color :negative-02)
|
|
||||||
:height 52}}
|
|
||||||
[react/text
|
|
||||||
{:style {:color (colors/get-color :negative-01)}}
|
|
||||||
(i18n/label :t/non-archival-node)]])
|
|
||||||
|
|
||||||
(defn history-list
|
|
||||||
[{:keys [transaction-history-sections total]} address]
|
|
||||||
(let [fetching-recent-history? @(re-frame/subscribe [:wallet-legacy/fetching-recent-tx-history?
|
|
||||||
address])
|
|
||||||
fetching-more-history? @(re-frame/subscribe [:wallet-legacy/fetching-tx-history? address])
|
|
||||||
keycard-account? @(re-frame/subscribe [:multiaccounts/keycard-account?])
|
|
||||||
custom-rpc-node? @(re-frame/subscribe [:custom-rpc-node])
|
|
||||||
non-archival-rpc-node? @(re-frame/subscribe [:wallet-legacy/non-archival-node])
|
|
||||||
binance-chain? @(re-frame/subscribe [:wallet-legacy/binance-chain?])
|
|
||||||
all-fetched? @(re-frame/subscribe [:wallet-legacy/tx-history-fetched? address])
|
|
||||||
syncing-allowed? @(re-frame/subscribe [:mobile-network/syncing-allowed?])]
|
|
||||||
[react/view {:flex 1}
|
|
||||||
[chain-explorer-link address]
|
|
||||||
(cond (or non-archival-rpc-node? binance-chain?)
|
|
||||||
[non-archival-node]
|
|
||||||
custom-rpc-node?
|
|
||||||
[custom-node])
|
|
||||||
(when fetching-recent-history?
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:height 40
|
|
||||||
:margin-vertical 16}}
|
|
||||||
[react/activity-indicator
|
|
||||||
{:size :large
|
|
||||||
:animating true}]])
|
|
||||||
[list/section-list
|
|
||||||
{:sections transaction-history-sections
|
|
||||||
:key-fn :hash
|
|
||||||
:render-data {:keycard-account? keycard-account?}
|
|
||||||
:render-fn render-transaction
|
|
||||||
:empty-component
|
|
||||||
[react/i18n-text
|
|
||||||
{:style styles/empty-text
|
|
||||||
:key (if (or fetching-recent-history? fetching-more-history?)
|
|
||||||
:transactions-history-loading
|
|
||||||
:transactions-history-empty)}]}]
|
|
||||||
(when (and (not fetching-recent-history?)
|
|
||||||
(not= all-fetched? :all))
|
|
||||||
(if fetching-more-history?
|
|
||||||
[react/view
|
|
||||||
{:style {:flex 1
|
|
||||||
:height 40
|
|
||||||
:margin-vertical 8}}
|
|
||||||
[react/activity-indicator
|
|
||||||
{:size :large
|
|
||||||
:animating true}]]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:center
|
|
||||||
[quo/button
|
|
||||||
{:type :secondary
|
|
||||||
:disabled (and (not syncing-allowed?)
|
|
||||||
(or (= all-fetched? :all-preloaded)
|
|
||||||
(zero? total)))
|
|
||||||
:on-press (when-not fetching-more-history?
|
|
||||||
#(re-frame/dispatch
|
|
||||||
[:transactions/fetch-more address]))}
|
|
||||||
(i18n/label :t/transactions-load-more)]}]))]))
|
|
||||||
|
|
||||||
(defn details-header
|
|
||||||
[date type amount-text currency-text]
|
|
||||||
[list.item/list-item
|
|
||||||
(merge
|
|
||||||
{:title [react/nested-text {:style styles/details-header-value}
|
|
||||||
[{:accessibility-label :amount-text} amount-text]
|
|
||||||
" "
|
|
||||||
[{:accessibility-label :currency-text} currency-text]]
|
|
||||||
:subtitle date}
|
|
||||||
(transaction-type->icon type))])
|
|
||||||
|
|
||||||
(defn progress-bar
|
|
||||||
[progress failed?]
|
|
||||||
[react/view {:style styles/progress-bar}
|
|
||||||
[react/view {:style (styles/progress-bar-done progress failed?)}]
|
|
||||||
[react/view {:style (styles/progress-bar-todo (- 100 progress) failed?)}]])
|
|
||||||
|
|
||||||
(defn details-confirmations
|
|
||||||
[confirmations confirmations-progress failed?]
|
|
||||||
[react/view {:style styles/details-block}
|
|
||||||
[progress-bar confirmations-progress failed?]
|
|
||||||
(if failed?
|
|
||||||
[react/i18n-text
|
|
||||||
{:style styles/details-failed
|
|
||||||
:key :failed}]
|
|
||||||
[react/text {:style styles/details-confirmations-count}
|
|
||||||
(str confirmations " " (i18n/label :t/confirmations))])
|
|
||||||
[react/i18n-text
|
|
||||||
{:style styles/details-confirmations-helper-text
|
|
||||||
:key :confirmations-helper-text}]])
|
|
||||||
|
|
||||||
(defn details-list-row
|
|
||||||
([label props-value]
|
|
||||||
(details-list-row label props-value nil))
|
|
||||||
([label props-value extra-props-value]
|
|
||||||
(let [[props value] (if (string? props-value)
|
|
||||||
[nil props-value]
|
|
||||||
props-value)
|
|
||||||
[extra-props extra-value] (if (string? extra-props-value)
|
|
||||||
[nil extra-props-value]
|
|
||||||
extra-props-value)]
|
|
||||||
[react/view {:style styles/details-row}
|
|
||||||
[react/i18n-text {:style styles/details-item-label :key label}]
|
|
||||||
[react/view {:style styles/details-item-value-wrapper}
|
|
||||||
[quo/text
|
|
||||||
(merge {:size :small
|
|
||||||
:monospace true}
|
|
||||||
props)
|
|
||||||
(str (or value "-"))]
|
|
||||||
[quo/text
|
|
||||||
(merge {:size :small
|
|
||||||
:color :secondary
|
|
||||||
:monospace true}
|
|
||||||
extra-props)
|
|
||||||
(str extra-value)]]])))
|
|
||||||
|
|
||||||
(defn details-list
|
|
||||||
[{:keys [block from from-wallet from-contact
|
|
||||||
to to-wallet to-contact
|
|
||||||
gas-limit gas-price-gwei gas-price-eth gas-used
|
|
||||||
fee-cap-gwei tip-cap-gwei
|
|
||||||
cost nonce data]
|
|
||||||
:as tx}]
|
|
||||||
[react/view {:style styles/details-block}
|
|
||||||
[details-list-row :t/block block]
|
|
||||||
[details-list-row :t/hash (:hash tx)]
|
|
||||||
[details-list-row :t/from-capitalized
|
|
||||||
[{:accessibility-label (if from-wallet :sender-name-text :sender-address-text)}
|
|
||||||
(or from-wallet from-contact from)]
|
|
||||||
(when (or from-wallet from-contact)
|
|
||||||
[{:accessibility-label :sender-address-text}
|
|
||||||
from])]
|
|
||||||
[details-list-row :t/to-capitalized
|
|
||||||
[{:accessibility-label (if to-wallet :recipient-name-text :recipient-address-text)}
|
|
||||||
(or to-wallet to-contact to)]
|
|
||||||
(when (or to-wallet to-contact)
|
|
||||||
[{:accessibility-label :recipient-address-text}
|
|
||||||
to])]
|
|
||||||
[details-list-row :t/gas-limit [{:monospace true} gas-limit]]
|
|
||||||
[details-list-row :t/gas-price gas-price-gwei [{:monospace false} gas-price-eth]]
|
|
||||||
[details-list-row :t/fee-cap fee-cap-gwei]
|
|
||||||
[details-list-row :t/tip-cap tip-cap-gwei]
|
|
||||||
[details-list-row :t/gas-used gas-used]
|
|
||||||
[details-list-row :t/cost-fee [{:monospace false} cost]]
|
|
||||||
[details-list-row :t/nonce nonce]
|
|
||||||
[details-list-row :t/data data]])
|
|
||||||
|
|
||||||
(defn details-action
|
|
||||||
[tx-hash url]
|
|
||||||
[{:label (i18n/label :t/copy-transaction-hash)
|
|
||||||
:action #(react/copy-to-clipboard tx-hash)}
|
|
||||||
{:label (i18n/label :t/open-on-block-explorer)
|
|
||||||
:action #(.openURL ^js react/linking url)}])
|
|
||||||
|
|
||||||
(defview transaction-details-view
|
|
||||||
[tx-hash address]
|
|
||||||
(letsubs [{:keys [url type confirmations confirmations-progress
|
|
||||||
date amount-text currency-text]
|
|
||||||
:as transaction}
|
|
||||||
[:wallet-legacy.transactions.details/screen tx-hash address]]
|
|
||||||
[react/view {:flex 1}
|
|
||||||
;;TODO options should be replaced by bottom sheet ,and topbar should be used here
|
|
||||||
[topbar/topbar
|
|
||||||
{:title (i18n/label :t/transaction-details)
|
|
||||||
:right-accessories (when transaction
|
|
||||||
[{:icon :main-icons/more
|
|
||||||
:on-press #(list-selection/show {:options
|
|
||||||
(details-action tx-hash url)})}])}]
|
|
||||||
[react/scroll-view {:flex 1}
|
|
||||||
[details-header date type amount-text currency-text]
|
|
||||||
[details-confirmations confirmations confirmations-progress (= :failed type)]
|
|
||||||
[react/view {:style styles/details-separator}]
|
|
||||||
[details-list transaction]]]))
|
|
||||||
|
|
||||||
(defview transaction-details
|
|
||||||
[]
|
|
||||||
(letsubs [{tx-hash :hash address :address} [:get-screen-params]]
|
|
||||||
(when (and tx-hash address)
|
|
||||||
[transaction-details-view tx-hash address])))
|
|
|
@ -1,394 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.accounts.core
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ens.core :as ens.core]
|
|
||||||
[legacy.status-im.ethereum.mnemonic :as mnemonic]
|
|
||||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.list-selection :as list-selection]
|
|
||||||
[legacy.status-im.utils.deprecated-types :as types]
|
|
||||||
[legacy.status-im.utils.hex :as hex]
|
|
||||||
[legacy.status-im.utils.mobile-sync :as utils.mobile-sync]
|
|
||||||
[legacy.status-im.wallet.core :as wallet-legacy]
|
|
||||||
[legacy.status-im.wallet.prices :as prices]
|
|
||||||
[native-module.core :as native-module]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.constants :as constants]
|
|
||||||
[status-im.navigation.events :as navigation]
|
|
||||||
[taoensso.timbre :as log]
|
|
||||||
[utils.address :as address]
|
|
||||||
[utils.ens.stateofus :as stateofus]
|
|
||||||
[utils.ethereum.chain :as chain]
|
|
||||||
[utils.ethereum.eip.eip55 :as eip55]
|
|
||||||
[utils.ethereum.eip.eip681 :as eip681]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf]
|
|
||||||
[utils.security.core :as security]))
|
|
||||||
|
|
||||||
(rf/defn start-adding-new-account
|
|
||||||
{:events [:wallet-legacy.accounts/start-adding-new-account]}
|
|
||||||
[{:keys [db] :as cofx} {:keys [type] :as add-account}]
|
|
||||||
(let [{:keys [latest-derived-path]} (:profile/profile db)
|
|
||||||
path-num (inc latest-derived-path)
|
|
||||||
account (merge
|
|
||||||
{:color (rand-nth colors/account-colors)}
|
|
||||||
(when (= type :generate)
|
|
||||||
{:name (str "Account " path-num)}))]
|
|
||||||
(rf/merge cofx
|
|
||||||
{:db (assoc db :add-account (assoc add-account :account account))}
|
|
||||||
(navigation/navigate-to :add-new-account nil))))
|
|
||||||
|
|
||||||
(rf/defn new-account-error
|
|
||||||
{:events [::new-account-error]}
|
|
||||||
[{:keys [db]} error-key error]
|
|
||||||
{:db (update db
|
|
||||||
:add-account
|
|
||||||
merge
|
|
||||||
{error-key error
|
|
||||||
:step nil})})
|
|
||||||
|
|
||||||
(defn account-stored
|
|
||||||
[path type]
|
|
||||||
(fn [result]
|
|
||||||
(let [{:keys [error publicKey address]} (types/json->clj result)]
|
|
||||||
(if error
|
|
||||||
(re-frame/dispatch [::new-account-error :account-error error])
|
|
||||||
(re-frame/dispatch [:wallet-legacy.accounts/account-stored
|
|
||||||
{:address address
|
|
||||||
:public-key publicKey
|
|
||||||
:type type
|
|
||||||
:path path}])))))
|
|
||||||
|
|
||||||
(defn normalize-path
|
|
||||||
[path]
|
|
||||||
(if (string/starts-with? path "m/")
|
|
||||||
(str constants/path-wallet-root
|
|
||||||
"/"
|
|
||||||
(last (string/split path "/")))
|
|
||||||
path))
|
|
||||||
|
|
||||||
(defn derive-and-store-account
|
|
||||||
[key-uid path hashed-password type accounts]
|
|
||||||
(fn [value]
|
|
||||||
(let [{:keys [id error keyUid]} (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 #(= derived-address (get % :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 address]} (get result (keyword path))]
|
|
||||||
(if error
|
|
||||||
(re-frame/dispatch [::new-account-error :account-error error])
|
|
||||||
(re-frame/dispatch
|
|
||||||
[:wallet-legacy.accounts/account-stored
|
|
||||||
{:address address
|
|
||||||
:public-key publicKey
|
|
||||||
:key-uid keyUid
|
|
||||||
:type type
|
|
||||||
:path (normalize-path path)}])))))))))))))
|
|
||||||
|
|
||||||
(def pass-error
|
|
||||||
"cannot retrieve a valid key for a given account: could not decrypt key with given password")
|
|
||||||
|
|
||||||
(defn store-account
|
|
||||||
[key-uid path hashed-password type]
|
|
||||||
(fn [value]
|
|
||||||
(let [{:keys [id error]} (types/json->clj value)]
|
|
||||||
(if error
|
|
||||||
(re-frame/dispatch [::new-account-error
|
|
||||||
(if (= error pass-error) :password-error :account-error)
|
|
||||||
error])
|
|
||||||
(native-module/multiaccount-store-account
|
|
||||||
id
|
|
||||||
key-uid
|
|
||||||
hashed-password
|
|
||||||
(account-stored path type))))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::verify-password
|
|
||||||
(fn [{:keys [address hashed-password]}]
|
|
||||||
(native-module/verify
|
|
||||||
address
|
|
||||||
hashed-password
|
|
||||||
#(re-frame/dispatch [:wallet-legacy.accounts/add-new-account-password-verified %
|
|
||||||
hashed-password]))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::generate-account
|
|
||||||
(fn [{:keys [derivation-info hashed-password accounts key-uid]}]
|
|
||||||
(let [{:keys [address path]} derivation-info]
|
|
||||||
(native-module/multiaccount-load-account
|
|
||||||
address
|
|
||||||
hashed-password
|
|
||||||
(derive-and-store-account key-uid path hashed-password :generated accounts)))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::import-account-seed
|
|
||||||
(fn [{:keys [passphrase hashed-password accounts key-uid]}]
|
|
||||||
(native-module/multiaccount-import-mnemonic
|
|
||||||
(mnemonic/sanitize-passphrase (security/unmask passphrase))
|
|
||||||
""
|
|
||||||
(derive-and-store-account key-uid constants/path-default-wallet hashed-password :seed accounts))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::import-account-private-key
|
|
||||||
(fn [{:keys [private-key hashed-password key-uid]}]
|
|
||||||
(native-module/multiaccount-import-private-key
|
|
||||||
(string/trim (security/unmask private-key))
|
|
||||||
(store-account key-uid constants/path-default-wallet hashed-password :key))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::validate-mnemonic
|
|
||||||
(fn [[passphrase callback]]
|
|
||||||
(native-module/validate-mnemonic passphrase callback)))
|
|
||||||
|
|
||||||
(rf/defn generate-new-account
|
|
||||||
[{:keys [db]} hashed-password]
|
|
||||||
(let [{:keys [key-uid wallet-root-address]}
|
|
||||||
(get db :profile/profile)
|
|
||||||
path-num (inc (get-in db [:profile/profile :latest-derived-path]))
|
|
||||||
accounts (:profile/wallet-accounts db)]
|
|
||||||
{:db (assoc-in db [:add-account :step] :generating)
|
|
||||||
::generate-account {:derivation-info {:path (str "m/" path-num)
|
|
||||||
:address wallet-root-address}
|
|
||||||
:hashed-password hashed-password
|
|
||||||
:accounts accounts
|
|
||||||
:key-uid key-uid}}))
|
|
||||||
|
|
||||||
(rf/defn import-new-account-seed
|
|
||||||
[{:keys [db]} passphrase hashed-password]
|
|
||||||
{:db (assoc-in db [:add-account :step] :generating)
|
|
||||||
::validate-mnemonic [(security/safe-unmask-data passphrase)
|
|
||||||
#(re-frame/dispatch [:wallet-legacy.accounts/seed-validated % passphrase
|
|
||||||
hashed-password])]})
|
|
||||||
|
|
||||||
(rf/defn new-account-seed-validated
|
|
||||||
{:events [:wallet-legacy.accounts/seed-validated]}
|
|
||||||
[{:keys [db] :as cofx} phrase-warnings passphrase hashed-password]
|
|
||||||
(let [error (:error (types/json->clj phrase-warnings))
|
|
||||||
{:keys [key-uid]} (:profile/profile db)]
|
|
||||||
(if-not (string/blank? error)
|
|
||||||
(new-account-error cofx :account-error error)
|
|
||||||
(let [accounts (:profile/wallet-accounts db)]
|
|
||||||
{::import-account-seed {:passphrase passphrase
|
|
||||||
:hashed-password hashed-password
|
|
||||||
:accounts accounts
|
|
||||||
:key-uid key-uid}}))))
|
|
||||||
|
|
||||||
(rf/defn import-new-account-private-key
|
|
||||||
[{:keys [db]} private-key hashed-password]
|
|
||||||
(let [{:keys [key-uid]} (:profile/profile db)]
|
|
||||||
{:db (assoc-in db [:add-account :step] :generating)
|
|
||||||
::import-account-private-key {:private-key private-key
|
|
||||||
:hashed-password hashed-password
|
|
||||||
:key-uid key-uid}}))
|
|
||||||
|
|
||||||
(rf/defn save-new-account
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(let [{:keys [latest-derived-path]} (:profile/profile db)
|
|
||||||
{:keys [account type]} (:add-account db)
|
|
||||||
{:keys [address name key-uid]} account
|
|
||||||
main-key-uid (or key-uid (get-in db [:profile/profile :key-uid]))
|
|
||||||
accounts (:profile/wallet-accounts db)
|
|
||||||
new-accounts (conj accounts account)
|
|
||||||
;; Note(rasom): in case if a new account is created using a mnemonic or
|
|
||||||
;; a private key we add a new keypair to the database, otherwise we just
|
|
||||||
;; keep using "profile" keypair
|
|
||||||
[method params]
|
|
||||||
(if key-uid
|
|
||||||
["accounts_saveKeypair"
|
|
||||||
[{:key-uid main-key-uid
|
|
||||||
:name name
|
|
||||||
:type (if (= type :seed)
|
|
||||||
"seed"
|
|
||||||
"key")
|
|
||||||
:derived-from address
|
|
||||||
:last-used-derivation-index 0
|
|
||||||
:synced-from ""
|
|
||||||
:clock 0
|
|
||||||
:accounts [account]}]]
|
|
||||||
["accounts_saveAccount"
|
|
||||||
[(assoc account :key-uid key-uid)]])]
|
|
||||||
(when account
|
|
||||||
(rf/merge cofx
|
|
||||||
{:json-rpc/call [{:method method
|
|
||||||
:params params
|
|
||||||
:on-success #(re-frame/dispatch [::wallet-legacy/restart])}]
|
|
||||||
:db (-> db
|
|
||||||
(assoc :profile/wallet-accounts new-accounts)
|
|
||||||
(dissoc :add-account))}
|
|
||||||
(when (= type :generate)
|
|
||||||
(multiaccounts.update/multiaccount-update
|
|
||||||
:latest-derived-path
|
|
||||||
(inc latest-derived-path)
|
|
||||||
{}))))))
|
|
||||||
|
|
||||||
(rf/defn account-generated
|
|
||||||
{:events [:wallet-legacy.accounts/account-stored]}
|
|
||||||
[{:keys [db] :as cofx} {:keys [address] :as account}]
|
|
||||||
(let [accounts (:profile/wallet-accounts db)]
|
|
||||||
(if (some #(when (= (:address %) address) %) accounts)
|
|
||||||
(new-account-error cofx :account-error (i18n/label :t/account-exists-title))
|
|
||||||
(rf/merge cofx
|
|
||||||
{:db (update-in db [:add-account :account] merge account)}
|
|
||||||
(save-new-account)
|
|
||||||
(if (utils.mobile-sync/syncing-allowed? cofx)
|
|
||||||
(wallet-legacy/set-max-block address 0)
|
|
||||||
(wallet-legacy/update-balances nil true))
|
|
||||||
(wallet-legacy/fetch-collectibles-collection)
|
|
||||||
(prices/update-prices)
|
|
||||||
(navigation/navigate-back)))))
|
|
||||||
|
|
||||||
(rf/defn add-watch-account
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(let [address (get-in db [:add-account :address])]
|
|
||||||
(account-generated cofx
|
|
||||||
{:address (eip55/address->checksum (address/normalized-hex address))
|
|
||||||
:type :watch})))
|
|
||||||
|
|
||||||
(rf/defn add-new-account-password-verified
|
|
||||||
{:events [:wallet-legacy.accounts/add-new-account-password-verified]}
|
|
||||||
[{:keys [db] :as cofx} result hashed-password]
|
|
||||||
(let [{:keys [error]} (types/json->clj result)]
|
|
||||||
(if (not (string/blank? error))
|
|
||||||
(new-account-error cofx :password-error error)
|
|
||||||
(let [{:keys [type seed private-key]} (:add-account db)]
|
|
||||||
(case type
|
|
||||||
:seed
|
|
||||||
(import-new-account-seed cofx seed hashed-password)
|
|
||||||
:key
|
|
||||||
(import-new-account-private-key cofx private-key hashed-password)
|
|
||||||
nil)))))
|
|
||||||
|
|
||||||
(rf/defn add-new-account-verify-password
|
|
||||||
[{:keys [db]} hashed-password]
|
|
||||||
{:db (assoc-in db [:add-account :step] :generating)
|
|
||||||
::verify-password {:address (get-in db [:profile/profile :wallet-root-address])
|
|
||||||
:hashed-password hashed-password}})
|
|
||||||
|
|
||||||
(rf/defn set-account-to-watch
|
|
||||||
{:events [:wallet-legacy.accounts/set-account-to-watch]}
|
|
||||||
[{:keys [db]} account]
|
|
||||||
(let [name? (and (>= (count account) 3)
|
|
||||||
(not (hex/valid-hex? account)))]
|
|
||||||
(log/debug "[wallet] set-account-to-watch" account
|
|
||||||
"name?" name?)
|
|
||||||
(cond-> {:db (assoc-in db [:add-account :address] account)}
|
|
||||||
name?
|
|
||||||
(assoc ::ens.core/resolve-address
|
|
||||||
[(chain/chain-id db)
|
|
||||||
(stateofus/ens-name-parse account)
|
|
||||||
#(re-frame/dispatch
|
|
||||||
[:wallet-legacy.accounts/set-account-to-watch %])]))))
|
|
||||||
|
|
||||||
(rf/defn add-new-account
|
|
||||||
{:events [:wallet-legacy.accounts/add-new-account]}
|
|
||||||
[{:keys [db] :as cofx} hashed-password]
|
|
||||||
(let [{:keys [type step]} (:add-account db)]
|
|
||||||
(log/debug "[wallet] add-new-account"
|
|
||||||
"type" type
|
|
||||||
"step" step)
|
|
||||||
(when-not step
|
|
||||||
(case type
|
|
||||||
:watch
|
|
||||||
(add-watch-account cofx)
|
|
||||||
:generate
|
|
||||||
(generate-new-account cofx hashed-password)
|
|
||||||
(:seed :key)
|
|
||||||
(add-new-account-verify-password cofx hashed-password)
|
|
||||||
nil))))
|
|
||||||
|
|
||||||
(rf/defn save-account
|
|
||||||
{:events [:wallet-legacy.accounts/save-account]}
|
|
||||||
[{:keys [db]} account {:keys [name color hidden]}]
|
|
||||||
(let [accounts (:profile/wallet-accounts db)
|
|
||||||
new-account (cond-> account
|
|
||||||
name (assoc :name name)
|
|
||||||
color (assoc :color color)
|
|
||||||
(not (nil? hidden)) (assoc :hidden hidden))
|
|
||||||
new-accounts (replace {account new-account} accounts)]
|
|
||||||
{:json-rpc/call [{:method "accounts_saveAccount"
|
|
||||||
:params [new-account]
|
|
||||||
:on-success #()}]
|
|
||||||
:db (assoc db :profile/wallet-accounts new-accounts)}))
|
|
||||||
|
|
||||||
(rf/defn delete-account
|
|
||||||
{:events [:wallet-legacy.accounts/delete-account]}
|
|
||||||
[{:keys [db] :as cofx} account]
|
|
||||||
(let [accounts (:profile/wallet-accounts db)
|
|
||||||
new-accounts (vec (remove #(= account %) accounts))
|
|
||||||
deleted-address (:address account)]
|
|
||||||
(rf/merge cofx
|
|
||||||
{:json-rpc/call [{:method "accounts_deleteAccount"
|
|
||||||
:params [(:address account)]
|
|
||||||
:on-success #()}]
|
|
||||||
:db (-> db
|
|
||||||
(assoc :profile/wallet-accounts new-accounts)
|
|
||||||
(update-in [:wallet-legacy :accounts] dissoc deleted-address))}
|
|
||||||
(navigation/pop-to-root :shell-stack))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
:key-storage/delete-imported-key
|
|
||||||
(fn [{:keys [key-uid address password on-success on-error]}]
|
|
||||||
(let [hashed-pass (native-module/sha3 (security/safe-unmask-data password))]
|
|
||||||
(native-module/delete-imported-key
|
|
||||||
key-uid
|
|
||||||
(string/lower-case (subs address 2))
|
|
||||||
hashed-pass
|
|
||||||
(fn [result]
|
|
||||||
(let [{:keys [error]} (types/json->clj result)]
|
|
||||||
(if-not (string/blank? error)
|
|
||||||
(on-error error)
|
|
||||||
(on-success))))))))
|
|
||||||
|
|
||||||
(rf/defn delete-account-key
|
|
||||||
{:events [:wallet-legacy.accounts/delete-key]}
|
|
||||||
[{:keys [db] :as cofx} account password on-error]
|
|
||||||
(let [deleted-address (:address account)
|
|
||||||
dapps-address (get-in cofx [:db :profile/profile :dapps-address])]
|
|
||||||
(if (= (string/lower-case dapps-address) (string/lower-case deleted-address))
|
|
||||||
{:effects.utils/show-popup {:title (i18n/label :t/warning)
|
|
||||||
:content (i18n/label :t/account-is-used)}}
|
|
||||||
{:key-storage/delete-imported-key
|
|
||||||
{:key-uid (get-in db [:profile/profile :key-uid])
|
|
||||||
:address (:address account)
|
|
||||||
:password password
|
|
||||||
:on-success #(do
|
|
||||||
(re-frame/dispatch [:hide-popover])
|
|
||||||
(re-frame/dispatch [:wallet-legacy.accounts/delete-account account]))
|
|
||||||
:on-error on-error}})))
|
|
||||||
|
|
||||||
(rf/defn view-only-qr-scanner-result
|
|
||||||
{:events [:wallet-legacy.add-new/qr-scanner-result]}
|
|
||||||
[{db :db :as cofx} data _]
|
|
||||||
(let [address (:address (eip681/parse-uri data))]
|
|
||||||
(rf/merge cofx
|
|
||||||
(merge {:db (-> db
|
|
||||||
(assoc-in [:add-account :scanned-address] address)
|
|
||||||
(assoc-in [:add-account :address] address))}
|
|
||||||
(when-not address
|
|
||||||
{:effects.utils/show-popup {:title (i18n/label :t/error)
|
|
||||||
:content (i18n/label :t/invalid-address-qr-code)}}))
|
|
||||||
(navigation/navigate-back))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
:list.selection/open-share
|
|
||||||
(fn [obj]
|
|
||||||
(list-selection/open-share obj)))
|
|
||||||
|
|
||||||
(rf/defn wallet-accounts-share
|
|
||||||
{:events [:wallet-legacy.accounts/share]}
|
|
||||||
[_ address]
|
|
||||||
{:list.selection/open-share {:message (eip55/address->checksum address)}})
|
|
|
@ -1,182 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.choose-recipient.core
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
|
|
||||||
[legacy.status-im.contact.db :as contact.db]
|
|
||||||
[legacy.status-im.ethereum.ens :as ens]
|
|
||||||
[legacy.status-im.ethereum.tokens :as tokens]
|
|
||||||
[legacy.status-im.qr-scanner.core :as qr-scaner]
|
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.common.router :as router]
|
|
||||||
[status-im.common.universal-links :as links]
|
|
||||||
[status-im.navigation.events :as navigation]
|
|
||||||
[utils.ethereum.chain :as chain]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.money :as money]
|
|
||||||
[utils.re-frame :as rf]
|
|
||||||
[utils.url :as url]))
|
|
||||||
|
|
||||||
;; FIXME(Ferossgp): Should be part of QR scanner not wallet
|
|
||||||
(rf/defn toggle-flashlight
|
|
||||||
{:events [:wallet-legacy/toggle-flashlight]}
|
|
||||||
[{:keys [db]}]
|
|
||||||
(let [flashlight-state (get-in db [:wallet-legacy :send-transaction :camera-flashlight])
|
|
||||||
toggled-state (if (= :on flashlight-state) :off :on)]
|
|
||||||
{:db (assoc-in db [:wallet-legacy :send-transaction :camera-flashlight] toggled-state)}))
|
|
||||||
|
|
||||||
(defn- find-address-name
|
|
||||||
[db address]
|
|
||||||
(:name (contact.db/find-contact-by-address (:contacts/contacts db) address)))
|
|
||||||
|
|
||||||
(rf/defn set-recipient
|
|
||||||
{:events [:wallet-legacy.send/set-recipient]}
|
|
||||||
[{:keys [db]} address]
|
|
||||||
{:db (-> db
|
|
||||||
(dissoc :wallet-legacy/recipient)
|
|
||||||
(assoc-in [:ui/search :recipient-filter] nil)
|
|
||||||
(assoc-in [:wallet-legacy/prepare-transaction :to] address))
|
|
||||||
:dispatch [:navigate-back]})
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::resolve-addresses
|
|
||||||
(fn [{:keys [chain-id ens-names callback]}]
|
|
||||||
;; resolve all addresses then call the callback function with the array of
|
|
||||||
;;addresses as parameter
|
|
||||||
(-> (js/Promise.all
|
|
||||||
(clj->js (mapv (fn [ens-name]
|
|
||||||
(js/Promise.
|
|
||||||
(fn [resolve-fn _]
|
|
||||||
(ens/address chain-id ens-name resolve-fn))))
|
|
||||||
ens-names)))
|
|
||||||
(.then callback)
|
|
||||||
(.catch (fn [error]
|
|
||||||
(js/console.log error))))))
|
|
||||||
|
|
||||||
(defn- fill-prepare-transaction-details
|
|
||||||
[db
|
|
||||||
{address :address
|
|
||||||
name :name
|
|
||||||
value :value
|
|
||||||
sym :symbol
|
|
||||||
gas :gas
|
|
||||||
gas-price :gasPrice
|
|
||||||
gas-limit :gasLimit
|
|
||||||
:or {sym :ETH}}
|
|
||||||
all-tokens]
|
|
||||||
(assoc db
|
|
||||||
:wallet-legacy/prepare-transaction
|
|
||||||
(cond-> {:to address
|
|
||||||
:to-name (or name (find-address-name db address))
|
|
||||||
:from (wallet.utils/get-default-account
|
|
||||||
(get db :profile/wallet-accounts))}
|
|
||||||
gas (assoc :gas (money/bignumber gas))
|
|
||||||
gas-limit (assoc :gas (money/bignumber gas-limit))
|
|
||||||
gas-price (assoc :gasPrice (money/bignumber gas-price))
|
|
||||||
value (assoc :amount-text
|
|
||||||
(if (= :ETH sym)
|
|
||||||
(str (money/internal->formatted value sym (get all-tokens sym)))
|
|
||||||
(str value)))
|
|
||||||
sym (assoc :symbol sym))))
|
|
||||||
|
|
||||||
(defn parse-eth-value
|
|
||||||
"Takes a map as returned by `parse-uri` and returns value as BigNumber"
|
|
||||||
[s]
|
|
||||||
(when (string? s)
|
|
||||||
(let [eth? (string/ends-with? s "ETH")
|
|
||||||
^js n (money/bignumber (string/replace s "ETH" ""))]
|
|
||||||
(if eth? (.times n 1e18) n))))
|
|
||||||
|
|
||||||
(defn extract-request-details
|
|
||||||
"Return a map encapsulating request details (with keys `value`, `address` and `symbol`) from a parsed URI.
|
|
||||||
Supports ethereum and erc20 token."
|
|
||||||
[{:keys [value address function-name function-arguments] :as details} all-tokens]
|
|
||||||
(when address
|
|
||||||
(merge details
|
|
||||||
(case function-name
|
|
||||||
nil
|
|
||||||
{:value (parse-eth-value value)
|
|
||||||
:symbol :ETH
|
|
||||||
:address address}
|
|
||||||
"transfer"
|
|
||||||
{:value (money/bignumber (:uint256 function-arguments))
|
|
||||||
:symbol (:symbol (tokens/address->token all-tokens address))
|
|
||||||
:address (:address function-arguments)}
|
|
||||||
nil))))
|
|
||||||
|
|
||||||
(rf/defn request-uri-parsed
|
|
||||||
{:events [:wallet-legacy/request-uri-parsed]}
|
|
||||||
[{{:networks/keys [networks current-network]
|
|
||||||
:wallet-legacy/keys [all-tokens]
|
|
||||||
:as db}
|
|
||||||
:db}
|
|
||||||
{:keys [chain-id] :as data}
|
|
||||||
uri]
|
|
||||||
(let [{:keys [address gasPrice] :as details}
|
|
||||||
(extract-request-details data all-tokens)]
|
|
||||||
(if address
|
|
||||||
(if (:wallet-legacy/recipient db)
|
|
||||||
{:db (update db
|
|
||||||
:wallet-legacy/recipient assoc
|
|
||||||
:resolved-address address
|
|
||||||
:address address)}
|
|
||||||
(if (:wallet-legacy/prepare-transaction db)
|
|
||||||
{:db (update db
|
|
||||||
:wallet-legacy/prepare-transaction assoc
|
|
||||||
:to address
|
|
||||||
:to-name (find-address-name db address))}
|
|
||||||
(let [current-chain-id (get-in networks [current-network :config :NetworkId])]
|
|
||||||
(merge {:db (fill-prepare-transaction-details db details all-tokens)
|
|
||||||
:dispatch [:open-modal :prepare-send-transaction]}
|
|
||||||
(when-not gasPrice
|
|
||||||
{:signing/update-gas-price
|
|
||||||
{:success-callback
|
|
||||||
#(re-frame/dispatch
|
|
||||||
[:wallet-legacy.send/update-gas-price-success :wallet-legacy/prepare-transaction
|
|
||||||
%])
|
|
||||||
:network-id (get-in (chain/current-network db)
|
|
||||||
[:config :NetworkId])}})
|
|
||||||
(when (and chain-id (not= current-chain-id chain-id))
|
|
||||||
{:ui/show-error (i18n/label :t/wallet-invalid-chain-id
|
|
||||||
{:data uri :chain current-chain-id})})))))
|
|
||||||
{:ui/show-error (i18n/label :t/wallet-invalid-address {:data uri})})))
|
|
||||||
|
|
||||||
(rf/defn qr-scanner-allowed
|
|
||||||
{:events [:wallet-legacy.send/qr-scanner]}
|
|
||||||
[{:keys [db] :as cofx} options]
|
|
||||||
(rf/merge cofx
|
|
||||||
(bottom-sheet/hide-bottom-sheet-old)
|
|
||||||
(qr-scaner/scan-qr-code options)))
|
|
||||||
|
|
||||||
(rf/defn parse-eip681-uri-and-resolve-ens
|
|
||||||
{:events [:wallet-legacy/parse-eip681-uri-and-resolve-ens]}
|
|
||||||
[{db :db :as cofx} {:keys [message uri paths ens-names error]} ignore-url]
|
|
||||||
(if-not error
|
|
||||||
;; first we get a vector of ens-names to resolve and a vector of paths of these names
|
|
||||||
(if (empty? ens-names)
|
|
||||||
;; if there are no ens-names, we dispatch request-uri-parsed immediately
|
|
||||||
(request-uri-parsed cofx message uri)
|
|
||||||
{::resolve-addresses
|
|
||||||
{:chain-id (chain/chain-id db)
|
|
||||||
:ens-names ens-names
|
|
||||||
:callback
|
|
||||||
(fn [addresses]
|
|
||||||
(re-frame/dispatch
|
|
||||||
[:wallet-legacy/request-uri-parsed
|
|
||||||
;; we replace ens-names at their path in the message by their actual address
|
|
||||||
(reduce (fn [message [path address]]
|
|
||||||
(assoc-in message path address))
|
|
||||||
message
|
|
||||||
(map vector paths addresses)) uri]))}})
|
|
||||||
(if (and (url/url? uri) (not ignore-url))
|
|
||||||
(if (links/universal-link? uri)
|
|
||||||
{:dispatch [:universal-links/handle-url uri]}
|
|
||||||
{:browser/show-browser-selection uri})
|
|
||||||
{:ui/show-error (i18n/label :t/wallet-invalid-address {:data uri})})))
|
|
||||||
|
|
||||||
(rf/defn qr-scanner-result
|
|
||||||
{:events [:wallet-legacy.send/qr-scanner-result]}
|
|
||||||
[cofx data {:keys [ignore-url]}]
|
|
||||||
(rf/merge cofx
|
|
||||||
(navigation/navigate-back)
|
|
||||||
(parse-eip681-uri-and-resolve-ens (router/match-eip681 data) ignore-url)))
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,128 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.custom-tokens.core
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.wallet.core :as wallet]
|
|
||||||
[legacy.status-im.wallet.prices :as prices]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.navigation.events :as navigation]
|
|
||||||
[utils.address :as address]
|
|
||||||
[utils.ethereum.chain :as chain]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
:wallet-legacy.custom-token/contract-address-paste
|
|
||||||
(fn []
|
|
||||||
(react/get-from-clipboard
|
|
||||||
#(re-frame/dispatch [:wallet-legacy.custom-token/contract-address-is-pasted (string/trim %)]))))
|
|
||||||
|
|
||||||
(defn field-exists?
|
|
||||||
[{:wallet-legacy/keys [all-tokens]} field-key field-value]
|
|
||||||
(some #(= field-value (get % field-key))
|
|
||||||
(vals all-tokens)))
|
|
||||||
|
|
||||||
(defn token-in-list?
|
|
||||||
[{:wallet-legacy/keys [all-tokens]} contract]
|
|
||||||
(not (nil? (get all-tokens (string/lower-case contract)))))
|
|
||||||
|
|
||||||
(rf/defn contract-address-is-changed
|
|
||||||
{:events [:wallet-legacy.custom-token/contract-address-is-pasted]}
|
|
||||||
[{:keys [db]} contract]
|
|
||||||
(if (address/address? contract)
|
|
||||||
(if (token-in-list? db contract)
|
|
||||||
{:db (assoc db
|
|
||||||
:wallet-legacy/custom-token-screen
|
|
||||||
{:contract contract :error (i18n/label :t/already-have-asset)})}
|
|
||||||
{:db (assoc db
|
|
||||||
:wallet-legacy/custom-token-screen
|
|
||||||
{:contract contract :in-progress? true})
|
|
||||||
:json-rpc/call [{:method "wallet_discoverToken"
|
|
||||||
:params [(chain/chain-id db) contract]
|
|
||||||
:on-success #(re-frame/dispatch
|
|
||||||
[:wallet-legacy.custom-token/token-discover-result %])
|
|
||||||
:on-error #(re-frame/dispatch [:wallet-legacy.custom-token/not-supported])}]})
|
|
||||||
{:db (assoc db
|
|
||||||
:wallet-legacy/custom-token-screen
|
|
||||||
{:contract contract
|
|
||||||
:error (i18n/label :t/wrong-address)})}))
|
|
||||||
|
|
||||||
(rf/defn token-discover-result
|
|
||||||
{:events [:wallet-legacy.custom-token/token-discover-result]}
|
|
||||||
[{:keys [db]} {:keys [name symbol decimals]}]
|
|
||||||
(let [symbol-exists? (field-exists? db :symbol (keyword symbol))]
|
|
||||||
{:db (update db
|
|
||||||
:wallet-legacy/custom-token-screen
|
|
||||||
merge
|
|
||||||
{:name name
|
|
||||||
:symbol symbol
|
|
||||||
:error-symbol (when symbol-exists?
|
|
||||||
(i18n/label :t/you-already-have-an-asset {:value symbol}))
|
|
||||||
:decimals (str decimals)
|
|
||||||
:in-progress? nil})}))
|
|
||||||
|
|
||||||
(rf/defn not-supported
|
|
||||||
{:events [:wallet-legacy.custom-token/not-supported]}
|
|
||||||
[{:keys [db]}]
|
|
||||||
{:db (assoc-in db [:wallet-legacy/custom-token-screen :in-progress?] nil)
|
|
||||||
:effects.utils/show-popup {:content (i18n/label :t/contract-isnt-supported)}})
|
|
||||||
|
|
||||||
(rf/defn add-custom-token
|
|
||||||
{:events [:wallet-legacy.custom-token.ui/add-pressed]}
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(let [{:keys [contract name symbol decimals]} (get db :wallet-legacy/custom-token-screen)
|
|
||||||
symbol (keyword symbol)
|
|
||||||
new-token {:address contract
|
|
||||||
:name name
|
|
||||||
:symbol symbol
|
|
||||||
:decimals (int decimals)
|
|
||||||
:color (rand-nth colors/chat-colors)}]
|
|
||||||
(rf/merge cofx
|
|
||||||
{:db (assoc-in db
|
|
||||||
[:wallet-legacy/all-tokens contract]
|
|
||||||
(assoc new-token :custom? true))
|
|
||||||
:json-rpc/call [{:method "wallet_addCustomToken"
|
|
||||||
:params [new-token]
|
|
||||||
:on-success #()}]}
|
|
||||||
(wallet/add-custom-token new-token)
|
|
||||||
(prices/update-prices)
|
|
||||||
(navigation/navigate-back))))
|
|
||||||
|
|
||||||
(rf/defn remove-custom-token
|
|
||||||
{:events [:wallet-legacy.custom-token.ui/remove-pressed]}
|
|
||||||
[{:keys [db] :as cofx} {:keys [address] :as token} navigate-back?]
|
|
||||||
(rf/merge cofx
|
|
||||||
{:db (update db :wallet-legacy/all-tokens dissoc address)
|
|
||||||
:json-rpc/call [{:method "wallet_deleteCustomToken"
|
|
||||||
:params [address]
|
|
||||||
:on-success #()}]}
|
|
||||||
(wallet/remove-custom-token token)
|
|
||||||
(when navigate-back?
|
|
||||||
(navigation/navigate-back))))
|
|
||||||
|
|
||||||
(rf/defn field-is-edited
|
|
||||||
{:events [:wallet-legacy.custom-token.ui/field-is-edited]}
|
|
||||||
[{:keys [db] :as cofx} field-key value]
|
|
||||||
(case field-key
|
|
||||||
:contract (contract-address-is-changed cofx value)
|
|
||||||
:name {:db (update db
|
|
||||||
:wallet-legacy/custom-token-screen
|
|
||||||
merge
|
|
||||||
{field-key
|
|
||||||
value
|
|
||||||
:error-name
|
|
||||||
(when (field-exists? db field-key value)
|
|
||||||
(i18n/label :t/you-already-have-an-asset
|
|
||||||
{:value value}))})}
|
|
||||||
:symbol {:db (update db
|
|
||||||
:wallet-legacy/custom-token-screen
|
|
||||||
merge
|
|
||||||
{field-key
|
|
||||||
value
|
|
||||||
:error-symbol
|
|
||||||
(when (field-exists? db field-key (keyword value))
|
|
||||||
(i18n/label :t/you-already-have-an-asset {:value value}))})}
|
|
||||||
:decimals {:db (assoc-in db
|
|
||||||
[:wallet-legacy/custom-token-screen :decimals]
|
|
||||||
value)}))
|
|
|
@ -1,55 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.db
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.utils.priority-map :refer [empty-transaction-map]]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.money :as money]))
|
|
||||||
|
|
||||||
(defn- too-precise-amount?
|
|
||||||
"Checks if number has any extra digit beyond the allowed number of decimals.
|
|
||||||
It does so by checking the number against its rounded value."
|
|
||||||
[amount decimals]
|
|
||||||
(let [^js bn (money/bignumber amount)]
|
|
||||||
(not (.eq bn
|
|
||||||
(.round bn decimals)))))
|
|
||||||
|
|
||||||
(defn parse-amount
|
|
||||||
[amount decimals]
|
|
||||||
(when-not (empty? amount)
|
|
||||||
(let [normalized-amount (money/normalize amount)
|
|
||||||
value (money/bignumber normalized-amount)]
|
|
||||||
(cond
|
|
||||||
(not (money/valid? value))
|
|
||||||
{:error (i18n/label :t/validation-amount-invalid-number) :value value}
|
|
||||||
|
|
||||||
(too-precise-amount? normalized-amount decimals)
|
|
||||||
{:error (i18n/label :t/validation-amount-is-too-precise {:decimals decimals}) :value value}
|
|
||||||
|
|
||||||
:else
|
|
||||||
{:value value}))))
|
|
||||||
|
|
||||||
(def default-wallet-filters
|
|
||||||
#{:inbound :outbound :pending :failed})
|
|
||||||
|
|
||||||
(def default-wallet
|
|
||||||
{:filters default-wallet-filters})
|
|
||||||
|
|
||||||
(defn get-confirmations
|
|
||||||
[{:keys [block]} current-block]
|
|
||||||
(if (and current-block block)
|
|
||||||
(inc (- current-block block))
|
|
||||||
0))
|
|
||||||
|
|
||||||
(defn remove-transactions-since-block
|
|
||||||
[accounts block]
|
|
||||||
(reduce-kv (fn [acc account-address account]
|
|
||||||
(assoc acc
|
|
||||||
account-address
|
|
||||||
(update account
|
|
||||||
:transactions
|
|
||||||
(fn [transactions]
|
|
||||||
(into empty-transaction-map
|
|
||||||
(drop-while (fn [[_ v]]
|
|
||||||
(>= (int (:block v)) block))
|
|
||||||
transactions))))))
|
|
||||||
{}
|
|
||||||
accounts))
|
|
|
@ -1,59 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.db-test
|
|
||||||
(:require
|
|
||||||
[cljs.test :refer-macros [deftest is testing]]
|
|
||||||
[legacy.status-im.wallet.db :as wallet.db]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.money :as money]))
|
|
||||||
|
|
||||||
(deftest test-too-precise-amount?
|
|
||||||
(testing "try both decimal and scientific or hex format"
|
|
||||||
(is (false? (#'legacy.status-im.wallet.db/too-precise-amount? "100" 2)))
|
|
||||||
(is (false? (#'legacy.status-im.wallet.db/too-precise-amount? "100" 0)))
|
|
||||||
(is (true? (#'legacy.status-im.wallet.db/too-precise-amount? "100.1" 0)))
|
|
||||||
(is (false? (#'legacy.status-im.wallet.db/too-precise-amount? "100.23" 2)))
|
|
||||||
(is (true? (#'legacy.status-im.wallet.db/too-precise-amount? "100.233" 2)))
|
|
||||||
(is (true? (#'legacy.status-im.wallet.db/too-precise-amount? "100.0000000000000000001" 18)))
|
|
||||||
(is (false? (#'legacy.status-im.wallet.db/too-precise-amount? "100.000000000000000001" 18)))
|
|
||||||
(is (false? (#'legacy.status-im.wallet.db/too-precise-amount? "1e-18" 18)))
|
|
||||||
(is (true? (#'legacy.status-im.wallet.db/too-precise-amount? "1e-19" 18)))
|
|
||||||
(is (true? (#'legacy.status-im.wallet.db/too-precise-amount? "0xa.a" 2))) ;; 0xa.a is 10.625
|
|
||||||
(is (false? (#'legacy.status-im.wallet.db/too-precise-amount? "0xa.a" 3)))
|
|
||||||
(is (false? (#'legacy.status-im.wallet.db/too-precise-amount? "1000" 3)))))
|
|
||||||
|
|
||||||
(defn- equal-results?
|
|
||||||
[a b]
|
|
||||||
(and (= (:error a) (:error b))
|
|
||||||
(or (and (nil? (:amount a))
|
|
||||||
(nil? (:amount b)))
|
|
||||||
(.eq ^js (:amount a) (:amount b)))))
|
|
||||||
|
|
||||||
(deftest test-parse-amount
|
|
||||||
(testing "test amount parsing"
|
|
||||||
(is (equal-results? {:value (money/bignumber "100")} (wallet.db/parse-amount "100" 2)))
|
|
||||||
(is (equal-results? {:value (money/bignumber "100")} (wallet.db/parse-amount "100" 0)))
|
|
||||||
(is (equal-results? {:error (i18n/label :t/validation-amount-is-too-precise {:decimals 0})
|
|
||||||
:value (money/bignumber "100.1")}
|
|
||||||
(wallet.db/parse-amount "100.1" 0)))
|
|
||||||
(is (equal-results? {:value (money/bignumber "100.23")} (wallet.db/parse-amount "100.23" 2)))
|
|
||||||
(is (equal-results? {:error (i18n/label :t/validation-amount-is-too-precise {:decimals 2})
|
|
||||||
:value (money/bignumber "100.233")}
|
|
||||||
(wallet.db/parse-amount "100.233" 2)))
|
|
||||||
(is (equal-results? {:error (i18n/label :t/validation-amount-is-too-precise {:decimals 18})
|
|
||||||
:value (money/bignumber "100.0000000000000000001")}
|
|
||||||
(wallet.db/parse-amount "100.0000000000000000001" 18)))
|
|
||||||
(is (equal-results? {:value (money/bignumber "100.000000000000000001")}
|
|
||||||
(wallet.db/parse-amount "100.000000000000000001" 18)))
|
|
||||||
(is (equal-results? {:value (money/bignumber "1e-18")} (wallet.db/parse-amount "1e-18" 18)))
|
|
||||||
(is (equal-results? {:error (i18n/label :t/validation-amount-is-too-precise {:decimals 18})
|
|
||||||
:value (money/bignumber "1e-19")}
|
|
||||||
(wallet.db/parse-amount "1e-19" 18)))
|
|
||||||
(is (equal-results? {:error (i18n/label :t/validation-amount-is-too-precise {:decimals 2})
|
|
||||||
:value (money/bignumber "10.625")}
|
|
||||||
(wallet.db/parse-amount "0xa.a" 2)))
|
|
||||||
(is (equal-results? {:value (money/bignumber "10.625")} (wallet.db/parse-amount "0xa.a" 3)))
|
|
||||||
(is (equal-results? {:error (i18n/label :t/validation-amount-invalid-number)
|
|
||||||
:value nil}
|
|
||||||
(wallet.db/parse-amount "SOMETHING" 5)))
|
|
||||||
(is (nil? (wallet.db/parse-amount nil 5)))
|
|
||||||
(is (nil? (wallet.db/parse-amount "" 5)))
|
|
||||||
(is (equal-results? {:value (money/bignumber "1000")} (wallet.db/parse-amount "1000" 3)))))
|
|
|
@ -1,77 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.prices
|
|
||||||
(:require
|
|
||||||
[clojure.set :as set]
|
|
||||||
[legacy.status-im.ethereum.tokens :as tokens]
|
|
||||||
[legacy.status-im.utils.currency :as currency]
|
|
||||||
[legacy.status-im.utils.prices :as prices]
|
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[taoensso.timbre :as log]
|
|
||||||
[utils.ethereum.chain :as chain]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
(defn assoc-error-message
|
|
||||||
[db error-type err]
|
|
||||||
(assoc-in db [:wallet-legacy :errors error-type] (or err :unknown-error)))
|
|
||||||
|
|
||||||
(defn clear-error-message
|
|
||||||
[db error-type]
|
|
||||||
(update-in db [:wallet-legacy :errors] dissoc error-type))
|
|
||||||
|
|
||||||
(defn tokens-symbols
|
|
||||||
[visible-token-symbols all-tokens]
|
|
||||||
(set/difference (set visible-token-symbols)
|
|
||||||
(set (map :symbol (tokens/nfts-for all-tokens)))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
:wallet-legacy/get-prices
|
|
||||||
(fn [{:keys [from to mainnet? success-event error-event]}]
|
|
||||||
(prices/get-prices from
|
|
||||||
to
|
|
||||||
mainnet?
|
|
||||||
#(re-frame/dispatch [success-event %])
|
|
||||||
#(re-frame/dispatch [error-event %]))))
|
|
||||||
|
|
||||||
(rf/defn on-update-prices-success
|
|
||||||
{:events [::update-prices-success]}
|
|
||||||
[{:keys [db]} prices]
|
|
||||||
{:db (assoc db
|
|
||||||
:prices prices
|
|
||||||
:prices-loading? false)})
|
|
||||||
|
|
||||||
(rf/defn on-update-prices-fail
|
|
||||||
{:events [::update-prices-fail]}
|
|
||||||
[{:keys [db]} err]
|
|
||||||
(log/debug "Unable to get prices: " err)
|
|
||||||
{:db (-> db
|
|
||||||
(assoc-error-message :prices-update :error-unable-to-get-prices)
|
|
||||||
(assoc :prices-loading? false))})
|
|
||||||
|
|
||||||
(rf/defn update-prices
|
|
||||||
{:events [:wallet-legacy.ui/pull-to-refresh]}
|
|
||||||
[{{:keys [network-status :wallet-legacy/all-tokens]
|
|
||||||
{:keys [currency :wallet-legacy/visible-tokens]
|
|
||||||
:or {currency :usd}}
|
|
||||||
:profile/profile
|
|
||||||
:as db}
|
|
||||||
:db}]
|
|
||||||
(let [chain (chain/chain-keyword db)
|
|
||||||
mainnet? (= :mainnet chain)
|
|
||||||
assets (get visible-tokens chain #{})
|
|
||||||
tokens (tokens-symbols assets all-tokens)
|
|
||||||
currency (get currency/currencies currency)]
|
|
||||||
(when (not= network-status :offline)
|
|
||||||
{:wallet-legacy/get-prices
|
|
||||||
{:from (if mainnet?
|
|
||||||
(conj tokens "ETH")
|
|
||||||
[(-> (tokens/native-currency (chain/get-current-network db))
|
|
||||||
(wallet.utils/exchange-symbol))])
|
|
||||||
:to [(:code currency)]
|
|
||||||
:mainnet? mainnet?
|
|
||||||
:success-event ::update-prices-success
|
|
||||||
:error-event ::update-prices-fail}
|
|
||||||
|
|
||||||
:db
|
|
||||||
(-> db
|
|
||||||
(clear-error-message :prices-update)
|
|
||||||
(assoc :prices-loading? true))})))
|
|
|
@ -1,107 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.recipient.core
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[legacy.status-im.ethereum.ens :as ens]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[legacy.status-im.utils.random :as random]
|
|
||||||
[legacy.status-im.utils.utils :as utils]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.common.json-rpc.events :as json-rpc]
|
|
||||||
[status-im.navigation.events :as navigation]
|
|
||||||
[utils.address :as address]
|
|
||||||
[utils.ens.core :as utils.ens]
|
|
||||||
[utils.ens.stateofus :as stateofus]
|
|
||||||
[utils.ethereum.chain :as chain]
|
|
||||||
[utils.ethereum.eip.eip55 :as eip55]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf]
|
|
||||||
[utils.string :as utils.string]))
|
|
||||||
|
|
||||||
;;NOTE we want to handle only last resolve
|
|
||||||
(def resolve-last-id (atom nil))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::resolve-address
|
|
||||||
(fn [{:keys [chain-id ens-name cb]}]
|
|
||||||
(ens/address chain-id ens-name cb)))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
:wallet-legacy.recipient/address-paste
|
|
||||||
(fn []
|
|
||||||
(react/get-from-clipboard
|
|
||||||
#(re-frame/dispatch [:wallet-legacy.recipient/address-changed (string/trim %)]))))
|
|
||||||
|
|
||||||
(rf/defn address-paste-pressed
|
|
||||||
{:events [:wallet-legacy.recipient/address-paste-pressed]}
|
|
||||||
[_]
|
|
||||||
{:wallet-legacy.recipient/address-paste nil})
|
|
||||||
|
|
||||||
(rf/defn set-recipient
|
|
||||||
{:events [::recipient-address-resolved]}
|
|
||||||
[{:keys [db] :as cofx} raw-recipient id]
|
|
||||||
(when (or (not id) (= id @resolve-last-id))
|
|
||||||
(reset! resolve-last-id nil)
|
|
||||||
(let [recipient (utils.string/safe-trim raw-recipient)]
|
|
||||||
(cond
|
|
||||||
(address/address? recipient)
|
|
||||||
(let [checksum (eip55/address->checksum recipient)]
|
|
||||||
(if (eip55/valid-address-checksum? checksum)
|
|
||||||
(rf/merge cofx
|
|
||||||
{:db (-> db
|
|
||||||
(assoc-in [:wallet-legacy/recipient :searching] false)
|
|
||||||
(assoc-in [:wallet-legacy/recipient :resolved-address] checksum))}
|
|
||||||
(json-rpc/call
|
|
||||||
{:method "eth_getCode"
|
|
||||||
:params [checksum "latest"]
|
|
||||||
:on-success #(when (not= "0x" %)
|
|
||||||
(utils/show-popup (i18n/label :t/warning)
|
|
||||||
(i18n/label
|
|
||||||
:t/warning-sending-to-contract-descr)))
|
|
||||||
:number-of-retries 3}))
|
|
||||||
{:ui/show-error (i18n/label :t/wallet-invalid-address-checksum {:data recipient})
|
|
||||||
:db (assoc-in db [:wallet-legacy/recipient :searching] false)}))
|
|
||||||
(and (not (string/blank? recipient))
|
|
||||||
(not (string/starts-with? recipient "0x"))
|
|
||||||
(utils.ens/valid-eth-name-prefix? recipient))
|
|
||||||
(let [ens-name (if (= (.indexOf ^js recipient ".") -1)
|
|
||||||
(stateofus/subdomain recipient)
|
|
||||||
recipient)]
|
|
||||||
(if (utils.ens/is-valid-eth-name? ens-name)
|
|
||||||
(do
|
|
||||||
(reset! resolve-last-id (random/id))
|
|
||||||
{::resolve-address
|
|
||||||
{:chain-id (chain/chain-id db)
|
|
||||||
:ens-name ens-name
|
|
||||||
:cb #(re-frame/dispatch [::recipient-address-resolved % @resolve-last-id])}})
|
|
||||||
{:db (assoc-in db [:wallet-legacy/recipient :searching] false)}))
|
|
||||||
:else
|
|
||||||
{:db (assoc-in db [:wallet-legacy/recipient :searching] false)}))))
|
|
||||||
|
|
||||||
(rf/defn address-changed
|
|
||||||
{:events [:wallet-legacy.recipient/address-changed]}
|
|
||||||
[{:keys [db] :as cofx} new-identity]
|
|
||||||
(rf/merge cofx
|
|
||||||
{:db (update db
|
|
||||||
:wallet-legacy/recipient assoc
|
|
||||||
:address new-identity
|
|
||||||
:resolved-address nil
|
|
||||||
:searching true)}
|
|
||||||
(set-recipient new-identity nil)))
|
|
||||||
|
|
||||||
(rf/defn recipient-modal-closed
|
|
||||||
{:events [:wallet-legacy/recipient-modal-closed]}
|
|
||||||
[{:keys [db]}]
|
|
||||||
{:db (dissoc db :wallet-legacy/recipient)})
|
|
||||||
|
|
||||||
(rf/defn add-favourite
|
|
||||||
{:events [:wallet-legacy/add-favourite]}
|
|
||||||
[{:keys [db] :as cofx} address name]
|
|
||||||
(let [new-favourite {:address address
|
|
||||||
:name (or name "")
|
|
||||||
:favourite true}]
|
|
||||||
(rf/merge cofx
|
|
||||||
{:db (assoc-in db [:wallet-legacy/favourites address] new-favourite)
|
|
||||||
:json-rpc/call [{:method "wallet_addSavedAddress"
|
|
||||||
:params [new-favourite]
|
|
||||||
:on-success #()}]}
|
|
||||||
(navigation/navigate-back))))
|
|
|
@ -1,52 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.swap.core
|
|
||||||
(:require
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[re-frame.db :as re-frame.db]
|
|
||||||
[status-im.navigation.events :as navigation]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
;; "source? true" means we are selecting the source asset. false implies
|
|
||||||
;; selection of sink asset."
|
|
||||||
(re-frame/reg-event-fx ::open-asset-selector-modal
|
|
||||||
(fn [{:keys [db]} [source?]]
|
|
||||||
{:db (assoc db :wallet-legacy/modal-selecting-source-token? source?)
|
|
||||||
:fx [[:dispatch [:open-modal :swap-asset-selector {}]]]}))
|
|
||||||
|
|
||||||
(rf/defn set-from-token
|
|
||||||
{:events [::set-from-token]}
|
|
||||||
[{:keys [db]} from-symbol]
|
|
||||||
(rf/merge {:db (assoc db :wallet-legacy/swap-from-token from-symbol)}
|
|
||||||
(navigation/navigate-back)))
|
|
||||||
|
|
||||||
(rf/defn set-to-token
|
|
||||||
{:events [::set-to-token]}
|
|
||||||
[{:keys [db]} to-symbol]
|
|
||||||
(rf/merge {:db (assoc db :wallet-legacy/swap-to-token to-symbol)}
|
|
||||||
(navigation/navigate-back)))
|
|
||||||
|
|
||||||
(rf/defn set-from-token-amount
|
|
||||||
[{:keys [db]} from-amount]
|
|
||||||
{:db (assoc db :wallet-legacy/swap-from-token-amount from-amount)})
|
|
||||||
|
|
||||||
(rf/defn set-max-from-token-amount
|
|
||||||
[{:keys [db]} _]
|
|
||||||
{:db (assoc db :wallet-legacy/swap-from-token-amount 0)})
|
|
||||||
|
|
||||||
(rf/defn switch-from-token-with-to
|
|
||||||
{:events [::switch-from-token-with-to]}
|
|
||||||
[{:keys [db]}]
|
|
||||||
{:db (assoc db
|
|
||||||
:wallet-legacy/swap-from-token (:wallet-legacy/swap-to-token db)
|
|
||||||
:wallet-legacy/swap-to-token (:wallet-legacy/swap-from-token db))})
|
|
||||||
|
|
||||||
(rf/defn set-advanced-mode
|
|
||||||
{:events [::set-advanced-mode]}
|
|
||||||
[{:keys [db]} mode]
|
|
||||||
{:db (assoc db :wallet-legacy/swap-advanced-mode? mode)})
|
|
||||||
|
|
||||||
(comment
|
|
||||||
(->> re-frame.db/app-db
|
|
||||||
deref
|
|
||||||
:wallet-legacy/all-tokens
|
|
||||||
vals
|
|
||||||
(map #(str (:name %) "-" (:symbol %)))))
|
|
|
@ -1,11 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.transactions-test
|
|
||||||
(:require
|
|
||||||
[cljs.test :refer-macros [deftest is]]
|
|
||||||
[legacy.status-im.ethereum.transactions.core :as transactions]))
|
|
||||||
|
|
||||||
(deftest get-transaction-details-url
|
|
||||||
(is (= "https://etherscan.io/tx/asdfasdf"
|
|
||||||
(transactions/get-transaction-details-url 1 "asdfasdf")))
|
|
||||||
(is (nil? (transactions/get-transaction-details-url 7787878 "asdfasdfg")))
|
|
||||||
(is (thrown? js/Error (transactions/get-transaction-details-url nil "asdfasdfg")))
|
|
||||||
(is (thrown? js/Error (transactions/get-transaction-details-url 676868 1))))
|
|
|
@ -1,37 +0,0 @@
|
||||||
(ns legacy.status-im.wallet.utils
|
|
||||||
(:require
|
|
||||||
[utils.money :as money]))
|
|
||||||
|
|
||||||
(defn format-amount
|
|
||||||
[amount decimals]
|
|
||||||
(-> amount
|
|
||||||
(or (money/bignumber 0))
|
|
||||||
(money/token->unit decimals)
|
|
||||||
money/to-fixed))
|
|
||||||
|
|
||||||
;;NOTE(goranjovic) - we are internally using symbol ETH for native currencies of any ethereum network
|
|
||||||
;; some sidechains have different names for this native currency, which we handle with `symbol-display`
|
|
||||||
;; override.
|
|
||||||
(defn display-symbol
|
|
||||||
[m]
|
|
||||||
(when-let [some-symbol (or (:symbol-display m) (:symbol m))]
|
|
||||||
(name some-symbol)))
|
|
||||||
|
|
||||||
;;NOTE(goranjovic) - in addition to custom symbol display, some sidechain native currencies are listed
|
|
||||||
;;under a different
|
|
||||||
;; ticker on exchange networks. We handle that with `symbol-exchange` override.
|
|
||||||
(defn exchange-symbol
|
|
||||||
[m]
|
|
||||||
(name (or (:symbol-exchange m)
|
|
||||||
(:symbol-display m)
|
|
||||||
(:symbol m))))
|
|
||||||
|
|
||||||
(defn get-default-account
|
|
||||||
[accounts]
|
|
||||||
(some #(when (:wallet %) %) accounts))
|
|
||||||
|
|
||||||
(defn default-address
|
|
||||||
[db]
|
|
||||||
(-> (get db :profile/wallet-accounts)
|
|
||||||
get-default-account
|
|
||||||
:address))
|
|
|
@ -13,7 +13,6 @@
|
||||||
[legacy.status-im.pairing.core :as models.pairing]
|
[legacy.status-im.pairing.core :as models.pairing]
|
||||||
[legacy.status-im.utils.deprecated-types :as types]
|
[legacy.status-im.utils.deprecated-types :as types]
|
||||||
[legacy.status-im.visibility-status-updates.core :as models.visibility-status-updates]
|
[legacy.status-im.visibility-status-updates.core :as models.visibility-status-updates]
|
||||||
[legacy.status-im.wallet.core :as wallet]
|
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.chat.contacts.events :as models.contact]
|
[status-im.contexts.chat.contacts.events :as models.contact]
|
||||||
[status-im.contexts.chat.events :as chat.events]
|
[status-im.contexts.chat.events :as chat.events]
|
||||||
|
@ -175,8 +174,7 @@
|
||||||
(do
|
(do
|
||||||
(js-delete response-js "accounts")
|
(js-delete response-js "accounts")
|
||||||
(rf/merge cofx
|
(rf/merge cofx
|
||||||
(process-next response-js sync-handler)
|
(process-next response-js sync-handler)))
|
||||||
(wallet/update-wallet-accounts (types/js->clj accounts))))
|
|
||||||
|
|
||||||
(seq settings)
|
(seq settings)
|
||||||
(do
|
(do
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns status-im.db
|
(ns status-im.db
|
||||||
(:require
|
(:require
|
||||||
[legacy.status-im.fleet.core :as fleet]
|
[legacy.status-im.fleet.core :as fleet]
|
||||||
[legacy.status-im.wallet.db :as wallet.db]
|
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im.contexts.shell.activity-center.events :as activity-center]))
|
[status-im.contexts.shell.activity-center.events :as activity-center]))
|
||||||
|
|
||||||
|
@ -19,8 +18,6 @@
|
||||||
:sync-state :done
|
:sync-state :done
|
||||||
:link-previews-whitelist []
|
:link-previews-whitelist []
|
||||||
:app-state "active"
|
:app-state "active"
|
||||||
:wallet-legacy wallet.db/default-wallet
|
|
||||||
:wallet-legacy/all-tokens {}
|
|
||||||
:peers-count 0
|
:peers-count 0
|
||||||
:node-info {}
|
:node-info {}
|
||||||
:peers-summary []
|
:peers-summary []
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
[legacy.status-im.fleet.core :as fleet]
|
[legacy.status-im.fleet.core :as fleet]
|
||||||
[legacy.status-im.multiaccounts.db :as multiaccounts.db]
|
[legacy.status-im.multiaccounts.db :as multiaccounts.db]
|
||||||
[legacy.status-im.utils.currency :as currency]
|
[legacy.status-im.utils.currency :as currency]
|
||||||
[legacy.status-im.wallet.utils :as wallet.utils]
|
|
||||||
[quo.theme :as theme]
|
[quo.theme :as theme]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.common.pixel-ratio :as pixel-ratio]
|
[status-im.common.pixel-ratio :as pixel-ratio]
|
||||||
|
@ -126,9 +125,9 @@
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:multiaccount/default-account
|
:multiaccount/default-account
|
||||||
:<- [:profile/wallet-accounts]
|
:<- [:wallet/accounts]
|
||||||
(fn [accounts]
|
(fn [accounts]
|
||||||
(wallet.utils/get-default-account accounts)))
|
(first accounts)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:multiaccount/visible-accounts
|
:multiaccount/visible-accounts
|
||||||
|
|
Loading…
Reference in New Issue