chore: remove legacy wallet code (#18749)

This commit is contained in:
Jamie Caprani 2024-02-25 20:00:56 +00:00 committed by GitHub
parent b0133e97cf
commit 42d2690c85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
69 changed files with 28 additions and 7839 deletions

View File

@ -1,7 +1,6 @@
(ns legacy.status-im.currency.core
(:require
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[legacy.status-im.wallet.prices :as prices]
[utils.re-frame :as rf]))
(defn get-currency
@ -16,5 +15,4 @@
:currency
currency
;; on changing currency, we should fetch tokens prices again
{:on-success #(rf/dispatch [:wallet/get-wallet-token])})
(prices/update-prices)))
{:on-success #(rf/dispatch [:wallet/get-wallet-token])})))

View File

@ -7,7 +7,6 @@
[legacy.status-im.ethereum.ens :as ens]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[legacy.status-im.utils.random :as random]
[legacy.status-im.wallet.utils :as wallet.utils]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.navigation.events :as navigation]
@ -126,7 +125,7 @@
{:events [::set-pub-key]}
[{:keys [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)
chain-id (chain/chain-id db)
username (fullname custom-domain? username)]

View File

@ -4,7 +4,6 @@
[legacy.status-im.ethereum.decode :as decode]
[legacy.status-im.ethereum.encode :as encode]
[legacy.status-im.utils.mobile-sync :as utils.mobile-sync]
[legacy.status-im.wallet.core :as wallet]
[re-frame.core :as re-frame]
[status-im.common.json-rpc.events :as json-rpc]
[taoensso.timbre :as log]
@ -256,24 +255,13 @@
(let [checksum (eip55/address->checksum address)
max-known-block (get-max-block-with-transfers db address)
effects (cond-> [(when (seq transfers)
(set-lowest-fetched-block checksum transfers))
(wallet/set-max-block-with-transfers checksum transfers)]
(set-lowest-fetched-block checksum transfers))]
(seq transfers)
(concat
[]
(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)
(conj (tx-history-end-reached checksum)))]
(apply rf/merge cofx (tx-fetching-ended [checksum]) effects)))
@ -282,8 +270,7 @@
{:events [::new-transfers]}
[cofx transfers params]
(rf/merge cofx
(handle-new-transfer transfers params)
(wallet/stop-fetching-on-empty-tx-history transfers)))
(handle-new-transfer transfers params)))
(rf/defn tx-fetching-failed
{:events [::tx-fetching-failed]}

View File

@ -32,10 +32,6 @@
legacy.status-im.visibility-status-popover.core
legacy.status-im.visibility-status-updates.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]
[re-frame.core :as re-frame]
[react-native.core :as rn]
@ -141,7 +137,6 @@
(rf/merge cofx
{:db (dissoc db :app-in-background-since)}
(mailserver/process-next-messages-request)
(wallet/restart-wallet-service-after-background app-in-background-since)
(when-not new-account?
(universal-links/process-stored-event))
#(when-let [chat-id (:current-chat-id db)]
@ -198,10 +193,8 @@
:reset-card (keycard/reset-card-screen-did-load %)
:enter-pin-settings (keycard/enter-pin-screen-did-load %)
:keycard-login-pin (keycard/login-pin-screen-did-load %)
:add-new-account-pin (keycard/enter-pin-screen-did-load %)
:keycard-authentication-method (keycard/authentication-method-screen-did-load %)
:multiaccounts (keycard/multiaccounts-screen-did-load %)
:wallet-legacy (wallet/wallet-will-focus %)
nil)))
;;TODO :replace by named events

View File

@ -401,15 +401,12 @@
(merge
args
{:on-success
(fn [response]
(fn [_response]
(log/debug "[keycard response succ] export-key")
(re-frame/dispatch [:keycard.callback/on-export-key-success
response]))
(js/alert "feature no longer supported"))
:on-failure
(fn [response]
(log/debug "[keycard response fail] export-key")
(re-frame/dispatch [:keycard.callback/on-export-key-error
(error-object->map response)]))})))
(fn [_response]
(log/debug "[keycard response fail] export-key"))})))
(defn unpair-and-delete
[args]

View File

@ -12,7 +12,6 @@
[legacy.status-im.keycard.recovery :as recovery]
[legacy.status-im.keycard.sign :as sign]
legacy.status-im.keycard.unpair
[legacy.status-im.keycard.wallet :as wallet]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[re-frame.db]
[status-im.navigation.events :as navigation]
@ -401,10 +400,6 @@
(= pin-code-length numbers-entered))
(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)
(= pin-code-length numbers-entered))
(sign/prepare-to-sign)

View File

@ -1,51 +1,13 @@
(ns legacy.status-im.keycard.export-key
(:require
[legacy.status-im.keycard.common :as common]
[legacy.status-im.keycard.wallet :as wallet]
[taoensso.timbre :as log]
[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
{:events [:keycard.callback/on-export-key-success]}
[{:keys [db] :as cofx} pubkey]
(let [callback-fn (get-in db [:keycard :on-export-success])]
(rf/merge cofx
{:dispatch (callback-fn pubkey)}
(wallet/hide-pin-sheet)
(common/clear-pin)
(common/hide-connection-sheet))))

View File

@ -3,7 +3,6 @@
[clojure.string :as string]
[legacy.status-im.keycard.common :as common]
[legacy.status-im.utils.deprecated-types :as types]
[legacy.status-im.wallet.utils :as wallet.utils]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[utils.address :as address]
@ -24,8 +23,7 @@
typed? (get-in db [:keycard :typed?])
pin (common/vector->string (get-in db [:keycard :pin :sign]))
from (or (get-in db [:signing/tx :from :address])
(get-in db [:signing/tx :message :from])
(wallet.utils/default-address db))
(get-in db [:signing/tx :message :from]))
path (reduce
(fn [_ {:keys [address path]}]
(when (address/address= from address)

View File

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

View File

@ -5,7 +5,6 @@
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[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.navigation.events :as navigation]
[taoensso.timbre :as log]
@ -35,7 +34,6 @@
(and logged-in? initialized?)
[(mailserver/process-next-messages-request)
(bottom-sheet/hide-bottom-sheet-old)
(wallet/restart-wallet-service nil)
#(add-new-contact/set-new-identity-reconnected %)]
logged-in?
@ -67,8 +65,7 @@
(boolean remember-choice?)
{})
(when (and cellular? sync?)
(mailserver/process-next-messages-request))
(wallet/restart-wallet-service nil))))))
(mailserver/process-next-messages-request)))))))
(rf/defn mobile-network-continue-syncing
{:events [:mobile-network/continue-syncing]}

View File

@ -1,6 +1,5 @@
(ns legacy.status-im.multiaccounts.logout.core
(:require
[legacy.status-im.wallet.core :as wallet]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[status-im.common.keychain.events :as keychain]
@ -39,7 +38,6 @@
:profile/get-profiles-overview #(rf/dispatch
[:profile/get-profiles-overview-success %])}
(keychain/save-auth-method key-uid auth-method)
(wallet/clear-timeouts)
(initialize-app-db))))
(rf/defn logout

View File

@ -2,7 +2,6 @@
(:require
["@react-native-community/netinfo" :default net-info]
[legacy.status-im.mobile-sync-settings.core :as mobile-network]
[legacy.status-im.wallet.core :as wallet]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
@ -11,12 +10,7 @@
(rf/defn change-network-status
[{:keys [db] :as cofx} is-connected?]
(rf/merge cofx
{: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))))
{:db (assoc db :network-status (if is-connected? :online :offline))}))
(rf/defn change-network-type
[{:keys [db] :as cofx} old-network-type network-type expensive?]

View File

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

View File

@ -10,9 +10,6 @@
[legacy.status-im.utils.deprecated-types :as types]
[legacy.status-im.utils.hex :as utils.hex]
[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]
[re-frame.core :as re-frame]
[status-im.common.json-rpc.events :as json-rpc]
@ -83,7 +80,7 @@
[{{:signing/keys [sign tx] :as db} :db}]
(let [{{:keys [data typed? from v4]} :message} tx
{:keys [in-progress? password]} sign
from (or from (wallet.utils/default-address db))
from from
hashed-password (native-module/sha3 (security/safe-unmask-data
password))]
(when-not in-progress?
@ -335,7 +332,7 @@
:dismiss-keyboard nil}
#(when-not wallet-set-up-passed?
{:dispatch-later [{:dispatch [:show-popover {:view :signing-phrase}] :ms 200}]})
(prices/update-prices)
#(when-not gas
{:db (assoc-in (:db %) [:signing/edit-fee :gas-loading?] true)
:signing/update-estimated-gas {:obj (-> tx-obj
@ -395,7 +392,6 @@
:signing/show-transaction-result nil}
(prepare-unconfirmed-transaction result tx-obj symbol amount)
(check-queue)
(wallet/watch-tx (get from :address) result)
#(when on-result
{:dispatch (conj on-result result)}))))
@ -408,7 +404,6 @@
(rf/merge
cofx
{:db (dissoc db :signing/tx :signing/sign)}
(wallet/watch-tx (get from :address) transaction-hash)
(if (keycard.common/keycard-multiaccount? db)
(signing.keycard/hash-message
{:data data
@ -511,8 +506,8 @@
{:dispatch (conj on-error "transaction was cancelled by user")}))))
(defn normalize-tx-obj
[db tx]
(update-in tx [:tx-obj :from] #(eip55/address->checksum (or % (wallet.utils/default-address db)))))
[_db tx]
(update-in tx [:tx-obj :from] #(eip55/address->checksum %)))
(rf/defn sign
"Signing transaction or message, shows signing sheet

View File

@ -1,7 +1,6 @@
(ns legacy.status-im.stickers.core
(:require
[legacy.status-im.utils.utils :as utils]
[legacy.status-im.wallet.utils :as wallet.utils]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[utils.ethereum.chain :as chain]
@ -39,15 +38,6 @@
:params []
: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
{:events [:stickers/pending-pack]}
[{db :db} id]

View File

@ -7,10 +7,6 @@
legacy.status-im.subs.mailservers
legacy.status-im.subs.networks
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]))
(defn reg-root-key-sub

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,6 @@
[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.views :as browser]
[legacy.status-im.ui.screens.wallet.components.views :as components]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[utils.i18n :as i18n]
@ -144,7 +143,7 @@
:container-style styles/input-container-style
:accessibility-label :dapp-url-input
:return-key-type :go}]
[components/separator-dark]
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]
[list/flat-list
{:header [list-header (empty? bookmarks)]
:data bookmarks

View File

@ -8,7 +8,6 @@
[legacy.status-im.ui.components.icons.icons :as icons]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.screens.wallet.components.views :as components]
[legacy.status-im.utils.utils :as utils]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
@ -32,7 +31,7 @@
:subtitle (utils/get-shortened-checksum-address (:address account))
:accessory [icons/icon :main-icons/check {:color colors/gray}]}]
[react/view {:padding-vertical 8}
[components/separator]]
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]]
[list.item/list-item
{:theme :negative
:title (i18n/label :t/revoke-access)
@ -86,7 +85,7 @@
(js/setTimeout
#(browser/share-link url)
200))}]
[components/separator]])
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]])
(if connected?
[list.item/list-item
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]

View File

@ -8,7 +8,6 @@
[legacy.status-im.ui.components.plus-button :as components.plus-button]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.components.topbar :as topbar]
[legacy.status-im.ui.screens.wallet.components.views :as components]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[utils.i18n :as i18n]
@ -67,7 +66,7 @@
:on-press #(do (re-frame/dispatch [:browser.ui/clear-all-browsers-pressed])
(re-frame/dispatch [:browser.ui/open-empty-tab]))}]
:title (i18n/label :t/tabs)}]
[components/separator-dark]
[react/view {:style {:height 1 :background-color (colors/alpha colors/black 0.1)}}]
[list/flat-list
{:data (conj browsers
{:empty-tab true

View File

@ -16,7 +16,6 @@
[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.styles :as styles]
[legacy.status-im.ui.screens.wallet.components.views :as components]
[legacy.status-im.utils.js-resources :as js-res]
[re-frame.core :as re-frame]
[react-native.permissions :as components.permissions]
@ -258,7 +257,7 @@
url-original (browser/get-current-url current-browser)]
[react/view {:style styles/browser}
[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
(when loading?
[connectivity/loading-indicator-anim window-width])]

View File

@ -16,7 +16,6 @@
[legacy.status-im.ui.components.topbar :as topbar]
[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.wallet.send.sheets :as sheets]
[legacy.status-im.utils.utils :as utils]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
@ -292,9 +291,7 @@
:title (:name account)
:subtitle (utils/get-shortened-checksum-address (:address account))
:chevron true
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
{:content (fn [] [sheets/accounts-list :from
::ens/change-address])}])}]))
:on-press #(js/alert "funcitonality no longer supported")}]))
(defn- registration
[checked contract address public-key]

View File

@ -9,8 +9,6 @@
[legacy.status-im.ui.screens.reset-password.views :as reset-password.views]
[legacy.status-im.ui.screens.signing.sheets :as signing-sheets]
[legacy.status-im.ui.screens.signing.views :as signing]
[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]
[react-native.platform :as platform]
[reagent.core :as reagent]))
@ -131,12 +129,6 @@
(vector? view)
view
(= :signing-phrase view)
[signing-phrase/signing-phrase]
(= :share-account view)
[request/share-address]
(= :share-chat-key view)
[profile.user/share-chat-key]

View File

@ -49,19 +49,6 @@
[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.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]
[utils.i18n :as i18n]))
@ -106,86 +93,11 @@
;;TODO custom subtitle
: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
:options {:topBar {:title {:text (i18n/label :t/main-currency)}}
:insets {:top? true}}
: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
{:name :my-profile
@ -404,20 +316,6 @@
:top? true}}
: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
{:name :qr-scanner
;;TODO custom topbar
@ -438,44 +336,6 @@
:top? true}}
: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
{:name :new-bookmark
;;TODO dynamic title

View File

@ -2,7 +2,6 @@
(:require-macros [legacy.status-im.utils.views :as views])
(:require
[clojure.string :as string]
[legacy.status-im.ethereum.tokens :as tokens]
[legacy.status-im.react-native.resources :as resources]
[legacy.status-im.signing.eip1559 :as eip1559]
[legacy.status-im.ui.components.bottom-panel.views :as bottom-panel]
@ -15,10 +14,8 @@
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.screens.signing.sheets :as sheets]
[legacy.status-im.ui.screens.signing.styles :as styles]
[legacy.status-im.ui.screens.wallet.components.views :as wallet.components]
[legacy.status-im.utils.deprecated-types :as types]
[legacy.status-im.utils.utils :as utils]
[legacy.status-im.wallet.utils :as wallet.utils]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.contexts.profile.utils :as profile.utils]
@ -57,11 +54,7 @@
:style {:margin-right 8}}
display-symbol]
(if icon
[wallet.components/token-icon
(assoc icon
:style {:background-color colors/gray-lighter
:border-radius 16}
:image-style {:width 24 :height 24})]
[react/view]
[chat-icon/custom-icon-view-list (:name token) color 32])]}]
[separator]]))
@ -328,7 +321,6 @@
[{:keys [from contact amount token cancel?] :as tx}]
(views/letsubs [fee [:signing/fee]
sign [:signing/sign]
chain [:current-network]
{:keys [amount-error gas-error gas-error-state insufficient-balalce?]}
[:signing/amount-errors (:address from)]
keycard-multiaccount? [:keycard-multiaccount?]
@ -337,8 +329,8 @@
mainnet? [:mainnet?]
prices-loading? [:prices-loading?]
management-enabled? [:wallet-legacy/transactions-management-enabled?]]
(let [display-symbol (wallet.utils/display-symbol token)
fee-display-symbol (wallet.utils/display-symbol (tokens/native-currency chain))]
(let [display-symbol nil
fee-display-symbol nil]
[react/view (styles/sheet)
[header sign tx display-symbol fee fee-display-symbol]
[separator]

View File

@ -38,7 +38,7 @@
(or owned free)
(re-frame/dispatch [:stickers/install-pack id])
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?))
(when (and (not free) (not owned))
[icons/tiny-icon :tiny-icons/tiny-snt

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,7 +13,6 @@
[legacy.status-im.pairing.core :as models.pairing]
[legacy.status-im.utils.deprecated-types :as types]
[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.contexts.chat.contacts.events :as models.contact]
[status-im.contexts.chat.events :as chat.events]
@ -175,8 +174,7 @@
(do
(js-delete response-js "accounts")
(rf/merge cofx
(process-next response-js sync-handler)
(wallet/update-wallet-accounts (types/js->clj accounts))))
(process-next response-js sync-handler)))
(seq settings)
(do

View File

@ -1,7 +1,6 @@
(ns status-im.db
(:require
[legacy.status-im.fleet.core :as fleet]
[legacy.status-im.wallet.db :as wallet.db]
[react-native.core :as rn]
[status-im.contexts.shell.activity-center.events :as activity-center]))
@ -19,8 +18,6 @@
:sync-state :done
:link-previews-whitelist []
:app-state "active"
:wallet-legacy wallet.db/default-wallet
:wallet-legacy/all-tokens {}
:peers-count 0
:node-info {}
:peers-summary []

View File

@ -5,7 +5,6 @@
[legacy.status-im.fleet.core :as fleet]
[legacy.status-im.multiaccounts.db :as multiaccounts.db]
[legacy.status-im.utils.currency :as currency]
[legacy.status-im.wallet.utils :as wallet.utils]
[quo.theme :as theme]
[re-frame.core :as re-frame]
[status-im.common.pixel-ratio :as pixel-ratio]
@ -126,9 +125,9 @@
(re-frame/reg-sub
:multiaccount/default-account
:<- [:profile/wallet-accounts]
:<- [:wallet/accounts]
(fn [accounts]
(wallet.utils/get-default-account accounts)))
(first accounts)))
(re-frame/reg-sub
:multiaccount/visible-accounts