Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat: integrate sendTransaction endpoint #18120

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/quo/components/wallet/token_input/component_spec.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
(h/describe "Wallet: Token Input"
(h/test "Token label renders"
(h/render [token-input/view
{:token :snt
{:token {:symbol "snt"}
:currency :eur
:conversion 1}])
(h/is-truthy (h/get-by-text "SNT")))

(h/test "Amount renders"
(h/render [token-input/view
{:token :snt
{:token {:symbol "snt"}
:currency :eur
:conversion 1}])
(h/is-truthy (h/get-by-text "€0.00"))))
2 changes: 1 addition & 1 deletion src/quo/components/wallet/token_input/view.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
:align-items :flex-end}}
[rn/image
{:style style/token
:source (resources/get-token token)}]
:source (resources/get-token (keyword (string/lower-case token)))}]
[rn/text-input
(cond-> {:auto-focus true
:ref #(reset! input-ref %)
Expand Down
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)
9 changes: 6 additions & 3 deletions src/status_im2/contexts/wallet/common/utils.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,15 @@
(when balance-in-chain
(calculate-raw-balance (:raw-balance balance-in-chain) decimals))))

(defn calculate-balance-for-token
[token]
(* (total-token-value-in-all-chains token)
(-> token :market-values-per-currency :usd :price)))

(defn calculate-balance
[tokens-in-account]
(->> tokens-in-account
(map (fn [token]
(* (total-token-value-in-all-chains token)
(-> token :market-values-per-currency :usd :price))))
(map #(calculate-balance-for-token %))
(reduce +)))

(defn network-list
Expand Down
133 changes: 133 additions & 0 deletions src/status_im2/contexts/wallet/send/events.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
(ns status-im2.contexts.wallet.send.events
(:require
[native-module.core :as native-module]
[status-im2.constants :as constants]
[taoensso.timbre :as log]
[utils.datetime :as datetime]
[utils.money :as money]
[utils.number]
[utils.re-frame :as rf]
[utils.security.core :as security]))

(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]} [address]]
{:db (assoc-in db [:wallet :ui :send :to-address] address)}))

(rf/reg-event-fx :wallet/send-select-token
(fn [{:keys [db]} [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]} [amount stack-id]]
{:db (assoc-in db [:wallet :ui :send :amount] amount)
:fx [[:navigate-to-within-stack [:wallet-transaction-confirmation stack-id]]]}))

(rf/reg-event-fx :wallet/get-suggested-routes
(fn [{:keys [db]} [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]
gas-rates constants/gas-rate-low
amount-in (money/mul (money/bignumber amount)
(money/from-decimal token-decimal))
from-address wallet-address
request-params [constants/send-type-transfer
from-address
to-address
(money/to-hex amount-in)
token-id
[]
[]
network-preferences
gas-rates
{}]
timestamp (datetime/timestamp)]
{:db (-> db
(assoc-in [:wallet :ui :send :loading-suggested-routes?] true)
(assoc-in [:wallet :ui :send :suggested-routes-call-timestamp]
timestamp))
:json-rpc/call [{:method "wallet_getSuggestedRoutes"
:params request-params
:on-success (fn [suggested-routes]
(rf/dispatch [:wallet/suggested-routes-success suggested-routes
timestamp]))
: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}))}]})))

(rf/reg-event-fx :wallet/send-transaction
(fn [{:keys [db]} [password]]
(let [route (get-in db [:wallet :ui :send :route])
from-address (get-in db [:wallet :current-viewing-account-address])
to-address (get-in db [:wallet :ui :send :to-address])
from (:From route)
token (get-in db [:wallet :ui :send :token])
token-id (:symbol token)
from-asset token-id
to-asset token-id
bridge-name (:BridgeName route)
chain-id (:chainId from)
multi-transaction-command {:fromAddress from-address
:toAddress to-address
:fromAsset from-asset
:toAsset to-asset
:fromAmount (:AmountOut route)
:type 0}
transaction-bridge
[{:BridgeName bridge-name
:ChainID chain-id
:TransferTx {:From from-address
:To to-address
:Gas (money/to-hex (:GasAmount route))
:GasPrice (money/to-hex (money/->wei :gwei
(:gasPrice (:GasFees route))))
:Value (:AmountOut route)
:Nonce nil
:MaxFeePerGas (money/to-hex
(money/->wei :gwei
(:maxFeePerGasMedium (:GasFees route))))
:MaxPriorityFeePerGas (money/to-hex (money/->wei :gwei
(:maxPriorityFeePerGas
(:GasFees
route))))
:Input ""
:Data "0x"}}]
sha3-pwd (native-module/sha3 (str (security/safe-unmask-data password)))
request-params [multi-transaction-command transaction-bridge sha3-pwd]]
{:json-rpc/call [{:method "wallet_createMultiTransaction"
:params request-params
:on-success #(rf/dispatch [:dismiss-modal :wallet-select-address])
:on-error (fn [error]
(log/error "failed to send transaction"
{:event :wallet/send-transaction
:error error
:params request-params}))}]})))
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@
:short-name "eth"
:network-name :ethereum
:chain-id 1
:related-chain-id 5}]})
:related-chain-id 5}]
:wallet {:ui {:send {:token {:symbol "ETH"
:decimals 18
:total-balance 1
:total-balance-fiat 10
:loading-suggested-routes? false
:route {}}}}}})

(h/describe "Send > input amount screen"
(h/test "Default render"
Expand Down
125 changes: 76 additions & 49 deletions src/status_im2/contexts/wallet/send/input_amount/view.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im2.contexts.wallet.send.input-amount.style :as style]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

Expand Down Expand Up @@ -47,71 +48,88 @@
current))

(defn- f-view-internal
[{:keys [token limit rate]}]
(let [bottom (safe-area/get-bottom)
{:keys [currency]} (rf/sub [:profile/profile])
networks (rf/sub [:wallet/network-details])
;; Temporary values
token (or token :eth)
conversion-rate (or rate 10)
limit-crypto (or limit 2860000.32)
limit-fiat (* limit-crypto conversion-rate)
input-value (reagent/atom "")
current-limit (reagent/atom {:amount limit-crypto
:currency token})
handle-swap (fn [crypto?]
(let [num-value (parse-double @input-value)]
(reset! current-limit (if crypto?
{:amount limit-crypto
:currency token}
{:amount limit-fiat
:currency currency}))
(when (> num-value (:amount @current-limit))
(reset! input-value ""))))
handle-keyboard-press (fn [v]
(let [current-value @input-value
new-value (make-new-input current-value v)
num-value (or (parse-double new-value) 0)]
(when (<= num-value (:amount @current-limit))
(reset! input-value new-value)
(reagent/flush))))
handle-delete (fn [_]
(swap! input-value #(subs % 0 (dec (count %))))
(reagent/flush))
handle-on-change (fn [v]
(when (valid-input? @input-value v)
(let [num-value (or (parse-double v) 0)
current-limit-amount (:amount @current-limit)]
(if (> num-value current-limit-amount)
(reset! input-value (str current-limit-amount))
(reset! input-value v))
(reagent/flush))))]
[{:keys [rate]}]
(let [bottom (safe-area/get-bottom)
{:keys [currency]} (rf/sub [:profile/profile])
networks (rf/sub [:wallet/network-details])
wallet-send (get-in (rf/sub [:wallet]) [:ui :send])
token (:token wallet-send)
token-symbol (:symbol token)
limit-crypto (:total-balance token)
limit-fiat (:total-balance-fiat token)
conversion-rate (or rate 10)
input-value (reagent/atom "")
current-limit (reagent/atom {:amount limit-crypto
:currency token-symbol})
loading-suggested-routes? (:loading-suggested-routes? wallet-send)
handle-swap (fn [crypto?]
(let [num-value (parse-double @input-value)]
(reset! current-limit (if crypto?
{:amount limit-crypto
:currency token-symbol}
{:amount limit-fiat
:currency currency}))
(when (> num-value (:amount @current-limit))
(reset! input-value ""))))
handle-keyboard-press (fn [v]
(let [current-value @input-value
new-value (make-new-input current-value v)
num-value (or (parse-double new-value) 0)]
(when (and (not loading-suggested-routes?)
(<= num-value (:amount @current-limit)))
(reset! input-value new-value)
(reagent/flush))))
handle-delete (fn [_]
(when-not loading-suggested-routes?
(swap! input-value #(subs % 0 (dec (count %))))
(reagent/flush)))
handle-on-change (fn [v]
(when (valid-input? @input-value v)
(let [num-value (or (parse-double v) 0)
current-limit-amount (:amount @current-limit)]
(if (> num-value current-limit-amount)
(reset! input-value (str current-limit-amount))
(reset! input-value v))
(reagent/flush))))]
(fn [{:keys [on-confirm]
:or {on-confirm #(js/alert "Confirmed")}}]
(let [limit-label (make-limit-label @current-limit)
input-num-value (parse-double @input-value)
confirm-disabled? (or
(empty? @input-value)
(<= input-num-value 0)
(> input-num-value (:amount @current-limit)))]
:or {on-confirm #(rf/dispatch [:wallet/send-select-amount @input-value
:wallet-send-input-amount])}}]
(let [limit-label (make-limit-label @current-limit)
input-num-value (parse-double @input-value)
route (get-in (rf/sub [:wallet]) [:ui :send :route])
loading-suggested-routes? (get-in (rf/sub [:wallet]) [:ui :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
(fn []
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)]
#(.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
{:style style/screen}
[quo/page-nav
{:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])
:on-press #(rf/dispatch [:navigate-back-within-stack :wallet-send-input-amount])
:right-side :account-switcher
:account-switcher {:customization-color :yellow
:emoji "🎮"
:on-press #(js/alert "Switch account")}}]
[quo/token-input
{:container-style style/input-container
:token token
:token token-symbol
:currency currency
:networks networks
:title (i18n/label :t/send-limit {:limit limit-label})
Expand All @@ -122,7 +140,16 @@
:on-change-text (fn [text]
(handle-on-change text))}]
;; 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
{:actions :1-action
:button-one-label (i18n/label :t/confirm)
Expand Down
Loading