Skip to content

Commit

Permalink
feat: implement getSuggestedRoutes in the wallet Send Flow
Browse files Browse the repository at this point in the history
Signed-off-by: Brian Sztamfater <brian@status.im>
  • Loading branch information
briansztamfater committed Dec 14, 2023
1 parent 16a52b3 commit a40a05e
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 139 deletions.
3 changes: 1 addition & 2 deletions src/status_im/multiaccounts/create/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,7 @@
:use-mailservers? true
:recovered recovered}
config/default-multiaccount)
;; The address from which we derive any chat
;; account/encryption keys
;; The address from which we derive any chat account/encryption keys
eip1581-address
(assoc :eip1581-address eip1581-address)
save-mnemonic?
Expand Down
12 changes: 12 additions & 0 deletions src/status_im2/constants.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,15 @@

(def ^:const status-address-domain ".stateofus.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)
12 changes: 12 additions & 0 deletions src/status_im2/contexts/wallet/common/utils.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@
(map total-token-fiat-value)
(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
[{:keys [balances-per-chain]} networks]
(into #{}
Expand Down
8 changes: 3 additions & 5 deletions src/status_im2/contexts/wallet/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@
(rf/defn clean-scanned-address
{:events [:wallet/clean-scanned-address]}
[{: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
(fn [{:keys [db]} [{:keys [sha3-pwd path]} on-success]]
Expand Down Expand Up @@ -426,10 +428,6 @@
(background-timer/clear-timeout current-timeout)
{: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
(fn [{:keys [db]} [{:keys [hasActivity]}]]
{:db (assoc-in db
Expand Down
2 changes: 1 addition & 1 deletion src/status_im2/contexts/wallet/events_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
(deftest clean-scanned-address
(let [db {:wallet/scanned-address address}]
(testing "clean-scanned-address"
(let [expected-db {}
(let [expected-db {:wallet {:ui {:send nil}}}
effects (events/clean-scanned-address {:db db})
result-db (:db effects)]
(is (match? result-db expected-db))))))
Expand Down
80 changes: 80 additions & 0 deletions src/status_im2/contexts/wallet/send/events.cljs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
(ns status-im2.contexts.wallet.send.events
(:require
[status-im2.constants :as constants]
[taoensso.timbre :as log]
[utils.money :as money]
[utils.number]
[utils.re-frame :as rf]))

Expand All @@ -10,3 +13,80 @@
(rf/reg-event-fx :wallet/select-send-account-address
(fn [{:keys [db]} [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 [constants/mainnet-chain-id] ; TODO: don't hardcode 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}))}]})))
157 changes: 83 additions & 74 deletions src/status_im2/contexts/wallet/send/input_amount/component_spec.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -12,98 +12,107 @@
(fn [_] (val keyval)))))

(def sub-mocks
{:profile/profile {:currency :usd}
:wallet/network-details [{:source 525
:short-name "eth"
:network-name :ethereum
:chain-id 1
:related-chain-id 5}]
:wallet/current-viewing-account {:path "m/44'/60'/0'/0/1"
:emoji "💎"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:ethereum :arbitrum :optimism}
:position 1
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false}})
{:profile/profile {:currency :usd}
:wallet/network-details [{:source 525
:short-name "eth"
:network-name :ethereum
:chain-id 1
:related-chain-id 5}]
:wallet/current-viewing-account {:path "m/44'/60'/0'/0/1"
:emoji "💎"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:ethereum :arbitrum
:optimism}
:position 1
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
: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/test "Default render"
(setup-subs sub-mocks)
(h/render [input-amount/view {}])
(h/is-truthy (h/get-by-text "0"))
(h/is-truthy (h/get-by-text "ETH"))
(h/is-truthy (h/get-by-text "$0.00"))
(h/is-disabled (h/get-by-label-text :button-one)))
(with-redefs [re-frame/dispatch #()]
(setup-subs sub-mocks)
(h/render [input-amount/view {}])
(h/is-truthy (h/get-by-text "0"))
(h/is-truthy (h/get-by-text "ETH"))
(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"
(setup-subs sub-mocks)
(let [on-confirm (h/mock-fn)]
(h/render [input-amount/view
{:on-confirm on-confirm
:rate 10}])
(with-redefs [re-frame/dispatch #()]
(setup-subs sub-mocks)
(let [on-confirm (h/mock-fn)]
(h/render [input-amount/view
{: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-2))
(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-4))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(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-3))
(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-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/was-called on-confirm)))
(h/fire-event :press (h/get-by-label-text :button-one))
(h/was-called on-confirm))))

(h/test "Try to fill more than limit"
(setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 286}])
(with-redefs [re-frame/dispatch #()]
(setup-subs sub-mocks)
(h/render [input-amount/view
{: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-9))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(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-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-8))
(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/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-5))
(h/wait-for #(h/is-truthy (h/get-by-text "$2850.00")))))

(h/test "Switch from crypto to fiat and check limit"
(setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 250}])
(with-redefs [re-frame/dispatch #()]
(setup-subs sub-mocks)
(h/render [input-amount/view
{: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-0))
(h/wait-for #(h/is-truthy (h/get-by-text "$200.00")))
(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/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/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/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH"))))))
Loading

0 comments on commit a40a05e

Please sign in to comment.