feat: implement getSuggestedRoutes in the wallet Send Flow (#18104)
Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
parent
d40f70dca4
commit
a4f99de8d5
|
@ -173,8 +173,7 @@
|
||||||
:use-mailservers? true
|
:use-mailservers? true
|
||||||
:recovered recovered}
|
:recovered recovered}
|
||||||
config/default-multiaccount)
|
config/default-multiaccount)
|
||||||
;; The address from which we derive any chat
|
;; The address from which we derive any chat account/encryption keys
|
||||||
;; account/encryption keys
|
|
||||||
eip1581-address
|
eip1581-address
|
||||||
(assoc :eip1581-address eip1581-address)
|
(assoc :eip1581-address eip1581-address)
|
||||||
save-mnemonic?
|
save-mnemonic?
|
||||||
|
|
|
@ -394,3 +394,15 @@
|
||||||
|
|
||||||
(def ^:const status-address-domain ".stateofus.eth")
|
(def ^:const status-address-domain ".stateofus.eth")
|
||||||
(def ^:const eth-address-domain ".eth")
|
(def ^:const eth-address-domain ".eth")
|
||||||
|
|
||||||
|
(def ^:const gas-rate-low 0)
|
||||||
|
(def ^:const gas-rate-medium 1)
|
||||||
|
(def ^:const gas-rate-high 2)
|
||||||
|
|
||||||
|
(def ^:const send-type-transfer 0)
|
||||||
|
(def ^:const send-type-ens-register 1)
|
||||||
|
(def ^:const send-type-ens-release 2)
|
||||||
|
(def ^:const send-type-ens-set-pub-key 3)
|
||||||
|
(def ^:const send-type-stickers-buy 4)
|
||||||
|
(def ^:const send-type-bridge 5)
|
||||||
|
(def ^:const send-type-erc-721-transfer 6)
|
||||||
|
|
|
@ -74,6 +74,18 @@
|
||||||
(map #(total-token-fiat-value currency %))
|
(map #(total-token-fiat-value currency %))
|
||||||
(reduce money/add)))
|
(reduce money/add)))
|
||||||
|
|
||||||
|
(defn calculate-balance-for-token
|
||||||
|
[token]
|
||||||
|
(money/bignumber
|
||||||
|
(money/mul (total-token-units-in-all-chains token)
|
||||||
|
(-> token :market-values-per-currency :usd :price))))
|
||||||
|
|
||||||
|
(defn calculate-balance
|
||||||
|
[tokens-in-account]
|
||||||
|
(->> tokens-in-account
|
||||||
|
(map #(calculate-balance-for-token %))
|
||||||
|
(reduce +)))
|
||||||
|
|
||||||
(defn network-list
|
(defn network-list
|
||||||
[{:keys [balances-per-chain]} networks]
|
[{:keys [balances-per-chain]} networks]
|
||||||
(into #{}
|
(into #{}
|
||||||
|
|
|
@ -152,7 +152,9 @@
|
||||||
(rf/defn clean-scanned-address
|
(rf/defn clean-scanned-address
|
||||||
{:events [:wallet/clean-scanned-address]}
|
{:events [:wallet/clean-scanned-address]}
|
||||||
[{:keys [db]}]
|
[{:keys [db]}]
|
||||||
{:db (dissoc db :wallet/scanned-address :wallet/send-address)})
|
{:db (-> db
|
||||||
|
(dissoc :wallet/scanned-address :wallet/send-address)
|
||||||
|
(update-in [:wallet :ui :send] dissoc :to-address))})
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/create-derived-addresses
|
(rf/reg-event-fx :wallet/create-derived-addresses
|
||||||
(fn [{:keys [db]} [{:keys [sha3-pwd path]} on-success]]
|
(fn [{:keys [db]} [{:keys [sha3-pwd path]} on-success]]
|
||||||
|
@ -437,10 +439,6 @@
|
||||||
(background-timer/clear-timeout current-timeout)
|
(background-timer/clear-timeout current-timeout)
|
||||||
{:db (assoc db :wallet/local-suggestions [] :wallet/valid-ens-or-address? false)})))
|
{:db (assoc db :wallet/local-suggestions [] :wallet/valid-ens-or-address? false)})))
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/select-send-address
|
|
||||||
(fn [{:keys [db]} [address]]
|
|
||||||
{:db (assoc db :wallet/send-address address)}))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/get-address-details-success
|
(rf/reg-event-fx :wallet/get-address-details-success
|
||||||
(fn [{:keys [db]} [{:keys [hasActivity]}]]
|
(fn [{:keys [db]} [{:keys [hasActivity]}]]
|
||||||
{:db (assoc-in db
|
{:db (assoc-in db
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
(deftest clean-scanned-address
|
(deftest clean-scanned-address
|
||||||
(let [db {:wallet/scanned-address address}]
|
(let [db {:wallet/scanned-address address}]
|
||||||
(testing "clean-scanned-address"
|
(testing "clean-scanned-address"
|
||||||
(let [expected-db {}
|
(let [expected-db {:wallet {:ui {:send nil}}}
|
||||||
effects (events/clean-scanned-address {:db db})
|
effects (events/clean-scanned-address {:db db})
|
||||||
result-db (:db effects)]
|
result-db (:db effects)]
|
||||||
(is (match? result-db expected-db))))))
|
(is (match? result-db expected-db))))))
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
(ns status-im2.contexts.wallet.send.events
|
(ns status-im2.contexts.wallet.send.events
|
||||||
(:require
|
(:require
|
||||||
|
[status-im2.constants :as constants]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[utils.money :as money]
|
||||||
[utils.number]
|
[utils.number]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -10,3 +13,79 @@
|
||||||
(rf/reg-event-fx :wallet/select-send-account-address
|
(rf/reg-event-fx :wallet/select-send-account-address
|
||||||
(fn [{:keys [db]} [address]]
|
(fn [{:keys [db]} [address]]
|
||||||
{:db (assoc db [:wallet :ui :send :send-account-address] address)}))
|
{:db (assoc db [:wallet :ui :send :send-account-address] address)}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/suggested-routes-success
|
||||||
|
(fn [{:keys [db]} [suggested-routes timestamp]]
|
||||||
|
(when (= (get-in db [:wallet :ui :send :suggested-routes-call-timestamp]) timestamp)
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:wallet :ui :send :suggested-routes] suggested-routes)
|
||||||
|
(assoc-in [:wallet :ui :send :route] (first (:Best suggested-routes)))
|
||||||
|
(assoc-in [:wallet :ui :send :loading-suggested-routes?] false))})))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/suggested-routes-error
|
||||||
|
(fn [{:keys [db]} [_error]]
|
||||||
|
{:db (-> db
|
||||||
|
(update-in [:wallet :ui :send] dissoc :suggested-routes)
|
||||||
|
(update-in [:wallet :ui :send] dissoc :route)
|
||||||
|
(assoc-in [:wallet :ui :send :loading-suggested-routes?] false))}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/clean-suggested-routes
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
{:db (-> db
|
||||||
|
(update-in [:wallet :ui :send] dissoc :suggested-routes)
|
||||||
|
(update-in [:wallet :ui :send] dissoc :route)
|
||||||
|
(update-in [:wallet :ui :send] dissoc :loading-suggested-routes?))}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/select-send-address
|
||||||
|
(fn [{:keys [db]} [{:keys [address stack-id]}]]
|
||||||
|
{:db (assoc-in db [:wallet :ui :send :to-address] address)
|
||||||
|
:fx [[:navigate-to-within-stack [:wallet-select-asset stack-id]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/send-select-token
|
||||||
|
(fn [{:keys [db]} [{:keys [token stack-id]}]]
|
||||||
|
{:db (assoc-in db [:wallet :ui :send :token] token)
|
||||||
|
:fx [[:navigate-to-within-stack [:wallet-send-input-amount stack-id]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/send-select-amount
|
||||||
|
(fn [{:keys [db]} [{:keys [amount]}]]
|
||||||
|
(js/alert "Not implemented yet")
|
||||||
|
{:db (assoc-in db [:wallet :ui :send :amount] amount)}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/get-suggested-routes
|
||||||
|
(fn [{:keys [db now]} [amount]]
|
||||||
|
(let [wallet-address (get-in db [:wallet :current-viewing-account-address])
|
||||||
|
token (get-in db [:wallet :ui :send :token])
|
||||||
|
to-address (get-in db [:wallet :ui :send :to-address])
|
||||||
|
token-decimal (:decimals token)
|
||||||
|
token-id (:symbol token)
|
||||||
|
network-preferences []
|
||||||
|
gas-rates constants/gas-rate-medium
|
||||||
|
amount-in (money/amount-in-hex amount token-decimal)
|
||||||
|
from-address wallet-address
|
||||||
|
disabled-from-chain-ids []
|
||||||
|
disabled-to-chain-ids []
|
||||||
|
from-locked-amount {}
|
||||||
|
request-params [constants/send-type-transfer
|
||||||
|
from-address
|
||||||
|
to-address
|
||||||
|
amount-in
|
||||||
|
token-id
|
||||||
|
disabled-from-chain-ids
|
||||||
|
disabled-to-chain-ids
|
||||||
|
network-preferences
|
||||||
|
gas-rates
|
||||||
|
from-locked-amount]]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:wallet :ui :send :loading-suggested-routes?] true)
|
||||||
|
(assoc-in [:wallet :ui :send :suggested-routes-call-timestamp] now))
|
||||||
|
:json-rpc/call [{:method "wallet_getSuggestedRoutes"
|
||||||
|
:params request-params
|
||||||
|
:on-success (fn [suggested-routes]
|
||||||
|
(rf/dispatch [:wallet/suggested-routes-success suggested-routes
|
||||||
|
now]))
|
||||||
|
:on-error (fn [error]
|
||||||
|
(rf/dispatch [:wallet/suggested-routes-error error])
|
||||||
|
(log/error "failed to get suggested routes"
|
||||||
|
{:event :wallet/get-suggested-routes
|
||||||
|
:error error
|
||||||
|
:params request-params}))}]})))
|
||||||
|
|
|
@ -12,98 +12,107 @@
|
||||||
(fn [_] (val keyval)))))
|
(fn [_] (val keyval)))))
|
||||||
|
|
||||||
(def sub-mocks
|
(def sub-mocks
|
||||||
{:profile/profile {:currency :usd}
|
{:profile/profile {:currency :usd}
|
||||||
:wallet/network-details [{:source 525
|
:wallet/network-details [{:source 525
|
||||||
:short-name "eth"
|
:short-name "eth"
|
||||||
:network-name :ethereum
|
:network-name :ethereum
|
||||||
:chain-id 1
|
:chain-id 1
|
||||||
:related-chain-id 5}]
|
:related-chain-id 5}]
|
||||||
:wallet/current-viewing-account {:path "m/44'/60'/0'/0/1"
|
:wallet/current-viewing-account {:path "m/44'/60'/0'/0/1"
|
||||||
:emoji "💎"
|
:emoji "💎"
|
||||||
:key-uid "0x2f5ea39"
|
:key-uid "0x2f5ea39"
|
||||||
:address "0x1"
|
:address "0x1"
|
||||||
:wallet false
|
:wallet false
|
||||||
:name "Account One"
|
:name "Account One"
|
||||||
:type :generated
|
:type :generated
|
||||||
:watch-only? false
|
:watch-only? false
|
||||||
:chat false
|
:chat false
|
||||||
:test-preferred-chain-ids #{5 420 421613}
|
:test-preferred-chain-ids #{5 420 421613}
|
||||||
:color :purple
|
:color :purple
|
||||||
:hidden false
|
:hidden false
|
||||||
:prod-preferred-chain-ids #{1 10 42161}
|
:prod-preferred-chain-ids #{1 10 42161}
|
||||||
:network-preferences-names #{:ethereum :arbitrum :optimism}
|
:network-preferences-names #{:ethereum :arbitrum
|
||||||
:position 1
|
:optimism}
|
||||||
:clock 1698945829328
|
:position 1
|
||||||
:created-at 1698928839000
|
:clock 1698945829328
|
||||||
:operable "fully"
|
:created-at 1698928839000
|
||||||
:mixedcase-address "0x7bcDfc75c431"
|
:operable "fully"
|
||||||
:public-key "0x04371e2d9d66b82f056bc128064"
|
:mixedcase-address "0x7bcDfc75c431"
|
||||||
:removed false}})
|
:public-key "0x04371e2d9d66b82f056bc128064"
|
||||||
|
:removed false}
|
||||||
|
:wallet/wallet-send-token {:symbol :eth}
|
||||||
|
:wallet/wallet-send-loading-suggested-routes? false
|
||||||
|
:wallet/wallet-send-route {:route []}})
|
||||||
|
|
||||||
(h/describe "Send > input amount screen"
|
(h/describe "Send > input amount screen"
|
||||||
(h/test "Default render"
|
(h/test "Default render"
|
||||||
(setup-subs sub-mocks)
|
(with-redefs [re-frame/dispatch #()]
|
||||||
(h/render [input-amount/view {}])
|
(setup-subs sub-mocks)
|
||||||
(h/is-truthy (h/get-by-text "0"))
|
(h/render [input-amount/view {}])
|
||||||
(h/is-truthy (h/get-by-text "ETH"))
|
(h/is-truthy (h/get-by-text "0"))
|
||||||
(h/is-truthy (h/get-by-text "$0.00"))
|
(h/is-truthy (h/get-by-text "ETH"))
|
||||||
(h/is-disabled (h/get-by-label-text :button-one)))
|
(h/is-truthy (h/get-by-text "$0.00"))
|
||||||
|
(h/is-disabled (h/get-by-label-text :button-one))))
|
||||||
|
|
||||||
(h/test "Fill token input and confirm"
|
(h/test "Fill token input and confirm"
|
||||||
(setup-subs sub-mocks)
|
(with-redefs [re-frame/dispatch #()]
|
||||||
(let [on-confirm (h/mock-fn)]
|
(setup-subs sub-mocks)
|
||||||
(h/render [input-amount/view
|
(let [on-confirm (h/mock-fn)]
|
||||||
{:on-confirm on-confirm
|
(h/render [input-amount/view
|
||||||
:rate 10}])
|
{:on-confirm on-confirm
|
||||||
|
:rate 10
|
||||||
|
:limit 1000}])
|
||||||
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-3))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-3))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-.))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-.))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-4))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-4))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||||
|
|
||||||
(h/wait-for #(h/is-truthy (h/get-by-text "$1234.50")))
|
(h/wait-for #(h/is-truthy (h/get-by-text "$1234.50")))
|
||||||
|
|
||||||
(h/is-truthy (h/get-by-label-text :button-one))
|
(h/is-truthy (h/get-by-label-text :button-one))
|
||||||
|
|
||||||
(h/fire-event :press (h/get-by-label-text :button-one))
|
(h/fire-event :press (h/get-by-label-text :button-one))
|
||||||
(h/was-called on-confirm)))
|
(h/was-called on-confirm))))
|
||||||
|
|
||||||
(h/test "Try to fill more than limit"
|
(h/test "Try to fill more than limit"
|
||||||
(setup-subs sub-mocks)
|
(with-redefs [re-frame/dispatch #()]
|
||||||
(h/render [input-amount/view
|
(setup-subs sub-mocks)
|
||||||
{:rate 10
|
(h/render [input-amount/view
|
||||||
:limit 286}])
|
{:rate 10
|
||||||
|
:limit 286}])
|
||||||
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||||
|
|
||||||
(h/wait-for #(h/is-truthy (h/get-by-text "$290.00")))
|
(h/wait-for #(h/is-truthy (h/get-by-text "$290.00")))
|
||||||
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-backspace))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-backspace))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-8))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-8))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||||
(h/wait-for #(h/is-truthy (h/get-by-text "$2850.00"))))
|
(h/wait-for #(h/is-truthy (h/get-by-text "$2850.00")))))
|
||||||
|
|
||||||
(h/test "Switch from crypto to fiat and check limit"
|
(h/test "Switch from crypto to fiat and check limit"
|
||||||
(setup-subs sub-mocks)
|
(with-redefs [re-frame/dispatch #()]
|
||||||
(h/render [input-amount/view
|
(setup-subs sub-mocks)
|
||||||
{:rate 10
|
(h/render [input-amount/view
|
||||||
:limit 250}])
|
{:rate 10
|
||||||
|
:limit 250}])
|
||||||
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-0))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-0))
|
||||||
(h/wait-for #(h/is-truthy (h/get-by-text "$200.00")))
|
(h/wait-for #(h/is-truthy (h/get-by-text "$200.00")))
|
||||||
|
|
||||||
(h/fire-event :press (h/query-by-label-text :reorder))
|
(h/fire-event :press (h/query-by-label-text :reorder))
|
||||||
|
|
||||||
(h/wait-for #(h/is-truthy (h/get-by-text "2.00 ETH")))
|
(h/wait-for #(h/is-truthy (h/get-by-text "2.00 ETH")))
|
||||||
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||||
|
|
||||||
(h/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH")))
|
(h/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH")))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||||
(h/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH")))))
|
(h/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH"))))))
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im2.contexts.wallet.common.account-switcher.view :as account-switcher]
|
[status-im2.contexts.wallet.common.account-switcher.view :as account-switcher]
|
||||||
[status-im2.contexts.wallet.send.input-amount.style :as style]
|
[status-im2.contexts.wallet.send.input-amount.style :as style]
|
||||||
|
[utils.debounce :as debounce]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -48,67 +49,84 @@
|
||||||
current))
|
current))
|
||||||
|
|
||||||
(defn- f-view-internal
|
(defn- f-view-internal
|
||||||
[{:keys [token limit rate]}]
|
[{:keys [rate limit]}]
|
||||||
(let [bottom (safe-area/get-bottom)
|
(let [bottom (safe-area/get-bottom)
|
||||||
{:keys [currency]} (rf/sub [:profile/profile])
|
{:keys [currency]} (rf/sub [:profile/profile])
|
||||||
networks (rf/sub [:wallet/network-details])
|
networks (rf/sub [:wallet/network-details])
|
||||||
;; Temporary values
|
token (rf/sub [:wallet/wallet-send-token])
|
||||||
token (or token :eth)
|
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||||
conversion-rate (or rate 10)
|
token-symbol (:symbol token)
|
||||||
limit-crypto (or limit 2860000.32)
|
limit-crypto (or (:total-balance token) limit)
|
||||||
limit-fiat (* limit-crypto conversion-rate)
|
conversion-rate (or rate 10)
|
||||||
input-value (reagent/atom "")
|
limit-fiat (* limit-crypto conversion-rate)
|
||||||
current-limit (reagent/atom {:amount limit-crypto
|
input-value (reagent/atom "")
|
||||||
:currency token})
|
current-limit (reagent/atom {:amount limit-crypto
|
||||||
handle-swap (fn [crypto?]
|
:currency token-symbol})
|
||||||
(let [num-value (parse-double @input-value)]
|
handle-swap (fn [crypto?]
|
||||||
(reset! current-limit (if crypto?
|
(let [num-value (parse-double @input-value)]
|
||||||
{:amount limit-crypto
|
(reset! current-limit (if crypto?
|
||||||
:currency token}
|
{:amount limit-crypto
|
||||||
{:amount limit-fiat
|
:currency token-symbol}
|
||||||
:currency currency}))
|
{:amount limit-fiat
|
||||||
(when (> num-value (:amount @current-limit))
|
:currency currency}))
|
||||||
(reset! input-value ""))))
|
(when (> num-value (:amount @current-limit))
|
||||||
handle-keyboard-press (fn [v]
|
(reset! input-value ""))))
|
||||||
(let [current-value @input-value
|
handle-keyboard-press (fn [v]
|
||||||
new-value (make-new-input current-value v)
|
(let [current-value @input-value
|
||||||
num-value (or (parse-double new-value) 0)]
|
new-value (make-new-input current-value v)
|
||||||
(when (<= num-value (:amount @current-limit))
|
num-value (or (parse-double new-value) 0)]
|
||||||
(reset! input-value new-value)
|
(when (and (not loading-suggested-routes?)
|
||||||
(reagent/flush))))
|
(<= num-value (:amount @current-limit)))
|
||||||
handle-delete (fn [_]
|
(reset! input-value new-value)
|
||||||
(swap! input-value #(subs % 0 (dec (count %))))
|
(reagent/flush))))
|
||||||
(reagent/flush))
|
handle-delete (fn [_]
|
||||||
handle-on-change (fn [v]
|
(when-not loading-suggested-routes?
|
||||||
(when (valid-input? @input-value v)
|
(swap! input-value #(subs % 0 (dec (count %))))
|
||||||
(let [num-value (or (parse-double v) 0)
|
(reagent/flush)))
|
||||||
current-limit-amount (:amount @current-limit)]
|
handle-on-change (fn [v]
|
||||||
(if (> num-value current-limit-amount)
|
(when (valid-input? @input-value v)
|
||||||
(reset! input-value (str current-limit-amount))
|
(let [num-value (or (parse-double v) 0)
|
||||||
(reset! input-value v))
|
current-limit-amount (:amount @current-limit)]
|
||||||
(reagent/flush))))]
|
(if (> num-value current-limit-amount)
|
||||||
|
(reset! input-value (str current-limit-amount))
|
||||||
|
(reset! input-value v))
|
||||||
|
(reagent/flush))))]
|
||||||
(fn [{:keys [on-confirm]
|
(fn [{:keys [on-confirm]
|
||||||
:or {on-confirm #(js/alert "Confirmed")}}]
|
:or {on-confirm #(rf/dispatch [:wallet/send-select-amount
|
||||||
(let [limit-label (make-limit-label @current-limit)
|
{:amount @input-value
|
||||||
input-num-value (parse-double @input-value)
|
:stack-id :wallet-send-input-amount}])}}]
|
||||||
confirm-disabled? (or
|
(let [limit-label (make-limit-label @current-limit)
|
||||||
(empty? @input-value)
|
input-num-value (parse-double @input-value)
|
||||||
(<= input-num-value 0)
|
route (rf/sub [:wallet/wallet-send-route])
|
||||||
(> input-num-value (:amount @current-limit)))]
|
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||||
|
confirm-disabled? (or
|
||||||
|
(nil? route)
|
||||||
|
(empty? @input-value)
|
||||||
|
(<= input-num-value 0)
|
||||||
|
(> input-num-value (:amount @current-limit)))]
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
||||||
app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)]
|
app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)]
|
||||||
#(.remove app-keyboard-listener))))
|
#(.remove app-keyboard-listener))))
|
||||||
|
(rn/use-effect (fn []
|
||||||
|
(rf/dispatch [:wallet/clean-suggested-routes])
|
||||||
|
(when-not (or
|
||||||
|
(empty? @input-value)
|
||||||
|
(<= input-num-value 0)
|
||||||
|
(> input-num-value (:amount @current-limit)))
|
||||||
|
(debounce/debounce-and-dispatch [:wallet/get-suggested-routes @input-value]
|
||||||
|
100)))
|
||||||
|
[@input-value])
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/screen}
|
{:style style/screen}
|
||||||
[account-switcher/view
|
[account-switcher/view
|
||||||
{:icon-name :i/arrow-left
|
{:icon-name :i/arrow-left
|
||||||
:on-press #(rf/dispatch [:navigate-back])
|
:on-press #(rf/dispatch [:navigate-back-within-stack :wallet-send-input-amount])
|
||||||
:switcher-type :select-account}]
|
:switcher-type :select-account}]
|
||||||
[quo/token-input
|
[quo/token-input
|
||||||
{:container-style style/input-container
|
{:container-style style/input-container
|
||||||
:token token
|
:token token-symbol
|
||||||
:currency currency
|
:currency currency
|
||||||
:networks networks
|
:networks networks
|
||||||
:title (i18n/label :t/send-limit {:limit limit-label})
|
:title (i18n/label :t/send-limit {:limit limit-label})
|
||||||
|
@ -119,7 +137,16 @@
|
||||||
:on-change-text (fn [text]
|
:on-change-text (fn [text]
|
||||||
(handle-on-change text))}]
|
(handle-on-change text))}]
|
||||||
;; Network routing content to be added
|
;; Network routing content to be added
|
||||||
[rn/scroll-view]
|
[rn/scroll-view
|
||||||
|
{:content-container-style {:flex-grow 1
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center}}
|
||||||
|
(cond loading-suggested-routes?
|
||||||
|
[quo/text "Loading routes"]
|
||||||
|
(and (not loading-suggested-routes?) route)
|
||||||
|
[quo/text "Route found"]
|
||||||
|
(and (not loading-suggested-routes?) (nil? route))
|
||||||
|
[quo/text "Route not found"])]
|
||||||
[quo/bottom-actions
|
[quo/bottom-actions
|
||||||
{:actions :1-action
|
{:actions :1-action
|
||||||
:button-one-label (i18n/label :t/confirm)
|
:button-one-label (i18n/label :t/confirm)
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
[input-value input-focused?]
|
[input-value input-focused?]
|
||||||
(fn []
|
(fn []
|
||||||
(let [scanned-address (rf/sub [:wallet/scanned-address])
|
(let [scanned-address (rf/sub [:wallet/scanned-address])
|
||||||
send-address (rf/sub [:wallet/send-address])
|
send-address (rf/sub [:wallet/wallet-send-to-address])
|
||||||
valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])
|
valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])
|
||||||
chain-id (rf/sub [:chain-id])
|
chain-id (rf/sub [:chain-id])
|
||||||
contacts (rf/sub [:contacts/active])]
|
contacts (rf/sub [:contacts/active])]
|
||||||
|
@ -76,7 +76,10 @@
|
||||||
_ _]
|
_ _]
|
||||||
(let [props {:on-press (fn []
|
(let [props {:on-press (fn []
|
||||||
(let [address (if accounts (:address (first accounts)) address)]
|
(let [address (if accounts (:address (first accounts)) address)]
|
||||||
(when-not ens (rf/dispatch [:wallet/select-send-address address]))))
|
(when-not ens
|
||||||
|
(rf/dispatch [:wallet/select-send-address
|
||||||
|
{:address address
|
||||||
|
:stack-id :wallet-select-address}]))))
|
||||||
:active-state? false}]
|
:active-state? false}]
|
||||||
(cond
|
(cond
|
||||||
(= type types/saved-address)
|
(= type types/saved-address)
|
||||||
|
@ -151,7 +154,9 @@
|
||||||
:type :primary
|
:type :primary
|
||||||
:disabled? (not valid-ens-or-address?)
|
:disabled? (not valid-ens-or-address?)
|
||||||
:container-style style/button
|
:container-style style/button
|
||||||
:on-press #(js/alert "Not implemented yet")}
|
:on-press #(rf/dispatch [:wallet/select-send-address
|
||||||
|
{:address @input-value
|
||||||
|
:stack-id :wallet-select-address}])}
|
||||||
(i18n/label :t/continue)])]
|
(i18n/label :t/continue)])]
|
||||||
[:<>
|
[:<>
|
||||||
[quo/tabs
|
[quo/tabs
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
(defn- asset-component
|
(defn- asset-component
|
||||||
[]
|
[]
|
||||||
(fn [token _ _ _]
|
(fn [token _ _ _]
|
||||||
(let [on-press #(js/alert "Not implemented yet")
|
(let [on-press
|
||||||
|
#(rf/dispatch [:wallet/send-select-token
|
||||||
|
{:token token
|
||||||
|
:stack-id :wallet-select-asset}])
|
||||||
total-balance-formatted (.toFixed (:total-balance token) 2)
|
total-balance-formatted (.toFixed (:total-balance token) 2)
|
||||||
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
|
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
|
||||||
currency-symbol (rf/sub [:profile/currency-symbol])]
|
currency-symbol (rf/sub [:profile/currency-symbol])]
|
||||||
[quo/token-network
|
[quo/token-network
|
||||||
{:token (:symbol token)
|
{:token (:symbol token)
|
||||||
:label (:name token)
|
:label (:name token)
|
||||||
|
|
|
@ -156,7 +156,6 @@
|
||||||
(reg-root-key-sub :wallet/networks :wallet/networks)
|
(reg-root-key-sub :wallet/networks :wallet/networks)
|
||||||
(reg-root-key-sub :wallet/local-suggestions :wallet/local-suggestions)
|
(reg-root-key-sub :wallet/local-suggestions :wallet/local-suggestions)
|
||||||
(reg-root-key-sub :wallet/valid-ens-or-address? :wallet/valid-ens-or-address?)
|
(reg-root-key-sub :wallet/valid-ens-or-address? :wallet/valid-ens-or-address?)
|
||||||
(reg-root-key-sub :wallet/send-address :wallet/send-address)
|
|
||||||
|
|
||||||
;;debug
|
;;debug
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
:<- [:wallet]
|
:<- [:wallet]
|
||||||
:-> :ui)
|
:-> :ui)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/wallet-send
|
||||||
|
:<- [:wallet/ui]
|
||||||
|
:-> :send)
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/tokens-loading?
|
:wallet/tokens-loading?
|
||||||
:<- [:wallet/ui]
|
:<- [:wallet/ui]
|
||||||
|
@ -40,6 +45,31 @@
|
||||||
:<- [:wallet]
|
:<- [:wallet]
|
||||||
:-> :current-viewing-account-address)
|
:-> :current-viewing-account-address)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/wallet-send-to-address
|
||||||
|
:<- [:wallet/wallet-send]
|
||||||
|
:-> :to-address)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/wallet-send-route
|
||||||
|
:<- [:wallet/wallet-send]
|
||||||
|
:-> :route)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/wallet-send-token
|
||||||
|
:<- [:wallet/wallet-send]
|
||||||
|
:-> :token)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/wallet-send-amount
|
||||||
|
:<- [:wallet/wallet-send]
|
||||||
|
:-> :amount)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/wallet-send-loading-suggested-routes?
|
||||||
|
:<- [:wallet/wallet-send]
|
||||||
|
:-> :loading-suggested-routes?)
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/watch-address-activity-state
|
:wallet/watch-address-activity-state
|
||||||
:<- [:wallet/ui]
|
:<- [:wallet/ui]
|
||||||
|
@ -110,7 +140,7 @@
|
||||||
(assoc token
|
(assoc token
|
||||||
:networks (utils/network-list token networks)
|
:networks (utils/network-list token networks)
|
||||||
:total-balance (utils/total-token-units-in-all-chains token)
|
:total-balance (utils/total-token-units-in-all-chains token)
|
||||||
:total-balance-fiat 0))
|
:total-balance-fiat (utils/calculate-balance-for-token token)))
|
||||||
(:tokens account))
|
(:tokens account))
|
||||||
sorted-tokens (sort-by :name compare tokens)
|
sorted-tokens (sort-by :name compare tokens)
|
||||||
filtered-tokens (filter #(or (string/starts-with? (string/lower-case (:name %))
|
filtered-tokens (filter #(or (string/starts-with? (string/lower-case (:name %))
|
||||||
|
|
|
@ -246,3 +246,7 @@
|
||||||
(schema/=> format-amount
|
(schema/=> format-amount
|
||||||
[:=> [:cat [:maybe :int]]
|
[:=> [:cat [:maybe :int]]
|
||||||
[:maybe :string]])
|
[:maybe :string]])
|
||||||
|
|
||||||
|
(defn amount-in-hex
|
||||||
|
[amount token-decimal]
|
||||||
|
(to-hex (mul (bignumber amount) (from-decimal token-decimal))))
|
||||||
|
|
Loading…
Reference in New Issue