* Update sending transaction end point * Transaction approval * Fixes * Fixes * Fixes * Fix for issue 3 * Fixes for 2, 4, 7 * Update * Fixes * Fixes
This commit is contained in:
parent
5f8d5fd57e
commit
de2b5fb935
|
@ -45,6 +45,12 @@
|
|||
"wallet.suggested.routes"
|
||||
{:fx [[:dispatch [:wallet/handle-suggested-routes (transforms/js->clj event-js)]]]}
|
||||
|
||||
"wallet.router.sign-transactions"
|
||||
{:fx [[:dispatch [:wallet/sign-transactions-signal-received (transforms/js->clj event-js)]]]}
|
||||
|
||||
"wallet.router.transactions-sent"
|
||||
{:fx [[:dispatch [:wallet/transactions-sent-signal-received (transforms/js->clj event-js)]]]}
|
||||
|
||||
"envelope.sent"
|
||||
(messages.transport/update-envelopes-status
|
||||
cofx
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
:on-close #(rf/dispatch [:standard-auth/reset-login-password])
|
||||
:content (fn []
|
||||
[keycard.pin/auth {:on-complete on-complete}])}]]]})
|
||||
|
||||
(rf/reg-event-fx :standard-auth/authorize-with-keycard authorize-with-keycard)
|
||||
|
||||
(defn authorize-with-password
|
||||
|
|
|
@ -565,6 +565,18 @@
|
|||
(:less-than-five-minutes constants/wallet-transaction-estimation) "3-5"
|
||||
">5"))
|
||||
|
||||
(defn transactions->hash-to-transaction-map
|
||||
[transactions]
|
||||
(reduce
|
||||
(fn [acc {to-chain :toChain tx-hash :hash}]
|
||||
(assoc acc
|
||||
tx-hash
|
||||
{:status :pending
|
||||
:id tx-hash
|
||||
:chain-id to-chain}))
|
||||
{}
|
||||
transactions))
|
||||
|
||||
(defn get-accounts-with-token-balance
|
||||
[accounts token]
|
||||
(let [operable-account (filter :operable? (vals accounts))
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
[promesa.core :as promesa]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.contexts.profile.recover.effects :as profile.recover.effects]
|
||||
[status-im.contexts.wallet.rpc :as wallet-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]
|
||||
|
@ -103,3 +104,22 @@
|
|||
(-> (verify-private-key-for-keypair keypair-key-uid private-key)
|
||||
(promesa/then (partial rf/call-continuation on-success))
|
||||
(promesa/catch (partial rf/call-continuation on-error)))))
|
||||
|
||||
(defn sign-transaction-hashes
|
||||
[hashes address password]
|
||||
(-> (promesa/all
|
||||
(for [h hashes]
|
||||
(promesa/let [signature (wallet-rpc/sign-message h address password)]
|
||||
{:message h
|
||||
:signature signature})))
|
||||
(promesa/catch (fn [err]
|
||||
(throw (ex-info "Failed to sign transaction hashes"
|
||||
{:error err
|
||||
:code :error/sign-transaction-hashes}))))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet/sign-transaction-hashes
|
||||
(fn [{:keys [hashes address password on-success on-error]}]
|
||||
(-> (sign-transaction-hashes hashes address password)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
|
|
@ -701,3 +701,36 @@
|
|||
(let [full-status (cske/transform-keys message transforms/->kebab-case-keyword)]
|
||||
{:db (assoc-in db [:wallet :blockchain] full-status)})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/sign-transactions-signal-received
|
||||
(fn [{:keys [db]} [{send-details :sendDetails :as data}]]
|
||||
(let [type (if (or (= (:fromToken send-details)
|
||||
(:toToken send-details))
|
||||
(string/blank? (:toToken send-details)))
|
||||
:send
|
||||
:swap)
|
||||
callback-fx (get-in db [:wallet :ui type :sign-transactions-callback-fx])
|
||||
error-response (:errorResponse send-details)]
|
||||
{:fx [(when (and callback-fx (not error-response))
|
||||
callback-fx)]
|
||||
:db (-> db
|
||||
(assoc-in [:wallet :ui type :sign-transactions-callback-fx] nil)
|
||||
(assoc-in [:wallet :ui type :error-response] error-response)
|
||||
(assoc-in [:wallet :ui type :transaction-for-signing] data))})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/transactions-sent-signal-received
|
||||
(fn [{:keys [db]}
|
||||
[{sent-transactions :sentTransactions
|
||||
send-details :sendDetails}]]
|
||||
(let [swap? (get-in db [:wallet :ui :swap])]
|
||||
{:fx [[:dispatch
|
||||
(if-let [error-response (:errorResponse send-details)]
|
||||
[(if swap?
|
||||
:wallet.swap/transaction-failure
|
||||
:wallet/transaction-failure)
|
||||
error-response]
|
||||
[(if swap?
|
||||
:wallet.swap/transaction-success
|
||||
:wallet/transaction-success)
|
||||
sent-transactions])]]})))
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
(ns status-im.contexts.wallet.rpc
|
||||
(:require [oops.core :as oops]
|
||||
[promesa.core :as promesa]
|
||||
[status-im.common.json-rpc.events :as rpc-events]
|
||||
[status-im.constants :as constants]
|
||||
[utils.hex]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn build-transaction
|
||||
[chain-id tx]
|
||||
(promesa/let [res (rpc-events/call-async "wallet_buildTransaction" true chain-id tx)]
|
||||
{:message-to-sign (oops/oget res :messageToSign)
|
||||
:tx-args (oops/oget res :txArgs)}))
|
||||
|
||||
(defn build-raw-transaction
|
||||
[chain-id tx-args signature]
|
||||
(-> (rpc-events/call-async "wallet_buildRawTransaction"
|
||||
true
|
||||
chain-id
|
||||
(transforms/js-stringify tx-args 0)
|
||||
signature)
|
||||
(promesa/then #(oops/oget % "rawTx"))))
|
||||
|
||||
(defn hash-message-eip-191
|
||||
[message]
|
||||
(rpc-events/call-async "wallet_hashMessageEIP191" true message))
|
||||
|
||||
(defn safe-sign-typed-data
|
||||
[data address password chain-id legacy?]
|
||||
(rpc-events/call-async "wallet_safeSignTypedDataForDApps"
|
||||
true
|
||||
data
|
||||
address
|
||||
password
|
||||
chain-id
|
||||
legacy?))
|
||||
|
||||
(defn get-suggested-fees
|
||||
[chain-id]
|
||||
(-> (rpc-events/call-async "wallet_getSuggestedFees" true chain-id)
|
||||
(promesa/then transforms/js->clj)))
|
||||
|
||||
(defn send-transaction-with-signature
|
||||
[chain-id tx-args signature]
|
||||
(rpc-events/call-async "wallet_sendTransactionWithSignature"
|
||||
true
|
||||
chain-id
|
||||
constants/transaction-pending-type-wallet-connect-transfer
|
||||
(transforms/js-stringify tx-args 0)
|
||||
signature))
|
||||
|
||||
(defn sign-message
|
||||
[message address password]
|
||||
(-> (rpc-events/call-async "wallet_signMessage"
|
||||
true
|
||||
message
|
||||
address
|
||||
password)
|
||||
(promesa/then utils.hex/normalize-hex)))
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im.contexts.wallet.send.events
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.collectible.utils :as collectible.utils]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
|
@ -9,11 +8,10 @@
|
|||
[status-im.contexts.wallet.data-store :as data-store]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.hex :as utils.hex]
|
||||
[utils.money :as utils.money]
|
||||
[utils.number]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-send-data
|
||||
(fn [{:keys [db]}]
|
||||
|
@ -327,22 +325,30 @@
|
|||
(rf/reg-event-fx
|
||||
:wallet/set-token-amount-to-send
|
||||
(fn [{:keys [db]} [{:keys [amount stack-id start-flow?]}]]
|
||||
{:db (assoc-in db [:wallet :ui :send :amount] amount)
|
||||
:fx [[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-send-flow}]]]}))
|
||||
(let [last-request-uuid (get-in db [:wallet :ui :send :last-request-uuid])]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :amount] amount)
|
||||
(update-in [:wallet :ui :send] dissoc :transaction-for-signing))
|
||||
:fx [[:dispatch [:wallet/build-transactions-from-route {:request-uuid last-request-uuid}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-send-flow}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-token-amount-to-bridge
|
||||
(fn [{:keys [db]} [{:keys [amount stack-id start-flow?]}]]
|
||||
{:db (assoc-in db [:wallet :ui :send :amount] amount)
|
||||
:fx [[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-bridge-flow}]]]}))
|
||||
(let [last-request-uuid (get-in db [:wallet :ui :send :last-request-uuid])]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :amount] amount)
|
||||
(update-in [:wallet :ui :send] dissoc :transaction-for-signing))
|
||||
:fx [[:dispatch [:wallet/build-transactions-from-route {:request-uuid last-request-uuid}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-bridge-flow}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/clean-bridge-to-selection
|
||||
|
@ -458,7 +464,8 @@
|
|||
:token-networks-ids token-networks-ids
|
||||
:tx-type tx-type
|
||||
:receiver? true}))
|
||||
params [{:uuid (str (random-uuid))
|
||||
request-uuid (str (random-uuid))
|
||||
params [{:uuid request-uuid
|
||||
:sendType send-type
|
||||
:addrFrom from-address
|
||||
:addrTo to-address
|
||||
|
@ -477,7 +484,8 @@
|
|||
{:db (update-in db
|
||||
[:wallet :ui :send]
|
||||
#(-> %
|
||||
(assoc :amount amount
|
||||
(assoc :last-request-uuid request-uuid
|
||||
:amount amount
|
||||
:loading-suggested-routes? true
|
||||
:sender-network-values sender-network-values
|
||||
:receiver-network-values receiver-network-values)
|
||||
|
@ -565,27 +573,39 @@
|
|||
:else [:wallet/suggested-routes-success (fix-routes data)
|
||||
enough-assets?])]]})))))
|
||||
|
||||
(rf/reg-event-fx :wallet/add-authorized-transaction
|
||||
(fn [{:keys [db]} [transaction]]
|
||||
(let [transaction-batch-id (:id transaction)
|
||||
transaction-hashes (:hashes transaction)
|
||||
transaction-ids (flatten (vals transaction-hashes))
|
||||
transaction-details (send-utils/map-multitransaction-by-ids transaction-batch-id
|
||||
transaction-hashes)]
|
||||
(rf/reg-event-fx
|
||||
:wallet/transaction-success
|
||||
(fn [{:keys [db]} [sent-transactions]]
|
||||
(let [wallet-transactions (get-in db [:wallet :transactions] {})
|
||||
transactions (utils/transactions->hash-to-transaction-map sent-transactions)
|
||||
transaction-ids (->> transactions
|
||||
vals
|
||||
(map :hash))]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :just-completed-transaction?] true)
|
||||
(assoc-in [:wallet :transactions] transaction-details)
|
||||
(assoc-in [:wallet :ui :send :transaction-ids] transaction-ids))
|
||||
:fx [;; Remove wallet/stop-and-clean-suggested-routes event when we move to new transaction
|
||||
;; submission process as the routes as stopped by status-go
|
||||
[:dispatch
|
||||
[:wallet/stop-and-clean-suggested-routes]]
|
||||
[:dispatch
|
||||
[:wallet/end-transaction-flow]]
|
||||
(assoc-in [:wallet :ui :send :transaction-ids] transaction-ids)
|
||||
(assoc-in [:wallet :transactions] (merge wallet-transactions transactions)))
|
||||
:fx [[:dispatch [:wallet/end-transaction-flow]]
|
||||
[:dispatch-later
|
||||
[{:ms 2000
|
||||
:dispatch [:wallet/stop-and-clean-suggested-routes]}]]
|
||||
[:dispatch-later
|
||||
[{:ms 2000
|
||||
:dispatch [:wallet/clean-just-completed-transaction]}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/transaction-failure
|
||||
(fn [_ [{:keys [details]}]]
|
||||
{:fx [[:dispatch [:wallet/end-transaction-flow]]
|
||||
[:dispatch-later
|
||||
[{:ms 2000
|
||||
:dispatch [:wallet/stop-and-clean-suggested-routes]}]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:id :send-transaction-failure
|
||||
:type :negative
|
||||
:text (or details "An error occured")}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-just-completed-transaction
|
||||
(fn [{:keys [db]}]
|
||||
{:db (update-in db [:wallet :ui :send] dissoc :just-completed-transaction?)}))
|
||||
|
@ -609,100 +629,65 @@
|
|||
[{:ms 20
|
||||
:dispatch [:wallet/clean-up-transaction-flow]}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/send-transaction
|
||||
(fn [{:keys [db]} [sha3-pwd]]
|
||||
(let [routes (get-in db [:wallet :ui :send :route])
|
||||
first-route (first routes)
|
||||
from-address (get-in db [:wallet :current-viewing-account-address])
|
||||
transaction-type (get-in db [:wallet :ui :send :tx-type])
|
||||
multi-transaction-type (if (= :tx/bridge transaction-type)
|
||||
constants/multi-transaction-type-bridge
|
||||
constants/multi-transaction-type-send)
|
||||
token (get-in db [:wallet :ui :send :token])
|
||||
collectible (get-in db [:wallet :ui :send :collectible])
|
||||
first-route-from-chain-id (get-in first-route [:from :chain-id])
|
||||
token-id (if token
|
||||
(:symbol token)
|
||||
(get-in collectible [:id :token-id]))
|
||||
erc20-transfer? (and token (not= token-id "ETH"))
|
||||
eth-transfer? (and token (not erc20-transfer?))
|
||||
token-address (cond collectible
|
||||
(get-in collectible
|
||||
[:id :contract-id :address])
|
||||
erc20-transfer?
|
||||
(get-in token [:balances-per-chain first-route-from-chain-id :address]))
|
||||
to-address (get-in db [:wallet :ui :send :to-address])
|
||||
transaction-paths (into []
|
||||
(mapcat
|
||||
(fn [route]
|
||||
(let [approval-required? (:approval-required route)
|
||||
data (when erc20-transfer?
|
||||
(native-module/encode-transfer
|
||||
(address/normalized-hex to-address)
|
||||
(:amount-in route)))
|
||||
base-path (utils/transaction-path
|
||||
{:to-address to-address
|
||||
:from-address from-address
|
||||
:route route
|
||||
:token-address token-address
|
||||
:token-id-from (if collectible
|
||||
(utils.hex/number-to-hex
|
||||
token-id)
|
||||
token-id)
|
||||
:data data
|
||||
:eth-transfer? eth-transfer?})]
|
||||
(if approval-required?
|
||||
[(utils/approval-path {:route route
|
||||
:token-address token-address
|
||||
:from-address from-address
|
||||
:to-address to-address})
|
||||
base-path]
|
||||
[base-path]))))
|
||||
routes)
|
||||
request-params
|
||||
[(utils/multi-transaction-command
|
||||
{:from-address from-address
|
||||
:to-address to-address
|
||||
:from-asset token-id
|
||||
:to-asset token-id
|
||||
:amount-out (if eth-transfer? (:amount-out first-route) "0x0")
|
||||
:multi-transaction-type multi-transaction-type})
|
||||
transaction-paths
|
||||
sha3-pwd]]
|
||||
(log/info "multi transaction called")
|
||||
{:json-rpc/call [{:method "wallet_createMultiTransaction"
|
||||
:params request-params
|
||||
:on-success (fn [result]
|
||||
(when result
|
||||
(rf/dispatch [:wallet/add-authorized-transaction result])
|
||||
(rf/dispatch [:hide-bottom-sheet])))
|
||||
(rf/reg-event-fx
|
||||
:wallet/build-transactions-from-route
|
||||
(fn [_ [{:keys [request-uuid slippage] :or {slippage constants/default-slippage}}]]
|
||||
{:json-rpc/call [{:method "wallet_buildTransactionsFromRoute"
|
||||
:params [{:uuid request-uuid
|
||||
:slippagePercentage slippage}]
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to build transactions from route"
|
||||
{:event :wallet/build-transactions-from-route
|
||||
:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :build-transactions-from-route-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/prepare-signatures-for-transactions
|
||||
(fn [{:keys [db]} [type sha3-pwd]]
|
||||
(let [transaction-for-signing (get-in db [:wallet :ui type :transaction-for-signing])]
|
||||
{:fx [[:effects.wallet/sign-transaction-hashes
|
||||
{:hashes (get-in transaction-for-signing [:signingDetails :hashes])
|
||||
:address (get-in transaction-for-signing [:signingDetails :address])
|
||||
:password (security/safe-unmask-data sha3-pwd)
|
||||
:on-success (fn [signatures]
|
||||
(rf/dispatch [:wallet/send-router-transactions-with-signatures type
|
||||
signatures]))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to prepare signatures for transactions"
|
||||
{:event :wallet/prepare-signatures-for-transactions
|
||||
:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :prepare-signatures-for-transactions-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/send-router-transactions-with-signatures
|
||||
(fn [{:keys [db]} [type signatures]]
|
||||
(let [transaction-for-signing (get-in db [:wallet :ui type :transaction-for-signing])
|
||||
signatures-map (reduce (fn [acc {:keys [message signature]}]
|
||||
(assoc acc
|
||||
message
|
||||
(send-utils/signature-rsv signature)))
|
||||
{}
|
||||
signatures)]
|
||||
{:json-rpc/call [{:method "wallet_sendRouterTransactionsWithSignatures"
|
||||
:params [{:uuid (get-in transaction-for-signing [:sendDetails :uuid])
|
||||
:signatures signatures-map}]
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to send transaction"
|
||||
{:event :wallet/send-transaction
|
||||
:error error
|
||||
:params request-params})
|
||||
(log/error "failed to send router transactions with signatures"
|
||||
{:event :wallet/send-router-transactions-with-signatures
|
||||
:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :send-transaction-error
|
||||
{:id :send-router-transactions-with-signatures-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/proceed-with-transactions-signatures
|
||||
(fn [_ [signatures]]
|
||||
{:json-rpc/call [{:method "wallet_proceedWithTransactionsSignatures"
|
||||
:params [signatures]
|
||||
:on-success (fn [result]
|
||||
(when result
|
||||
(rf/dispatch [:wallet/add-authorized-transaction result])
|
||||
(rf/dispatch [:hide-bottom-sheet])))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to proceed-with-transactions-signatures"
|
||||
{:event :wallet/proceed-with-transactions-signatures
|
||||
:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :send-transaction-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/select-from-account
|
||||
(fn [{db :db} [{:keys [address stack-id network-details start-flow?]}]]
|
||||
|
|
|
@ -575,29 +575,6 @@
|
|||
:from-locked-amounts {}}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id suggested-routes timestamp]))))))
|
||||
|
||||
(h/deftest-event :wallet/add-authorized-transaction
|
||||
[event-id dispatch]
|
||||
(let [hashes {:chain-1 ["tx-1" "tx-2" "tx-3"]
|
||||
:chain-2 ["tx-4" "tx-5"]
|
||||
:chain-3 ["tx-6" "tx-7" "tx-8" "tx-9"]}
|
||||
transaction-id "txid-1"
|
||||
expected-result {:db {:wallet {:ui {:send {:transaction-ids ["tx-1" "tx-2" "tx-3"
|
||||
"tx-4" "tx-5" "tx-6"
|
||||
"tx-7" "tx-8" "tx-9"]}}
|
||||
:transactions (send-utils/map-multitransaction-by-ids
|
||||
transaction-id
|
||||
hashes)}}
|
||||
:fx [[:dispatch
|
||||
[:wallet/stop-and-clean-suggested-routes]]
|
||||
[:dispatch [:wallet/end-transaction-flow]]
|
||||
[:dispatch-later
|
||||
[{:ms 2000
|
||||
:dispatch [:wallet/clean-just-completed-transaction]}]]]}]
|
||||
(is (match? expected-result
|
||||
(dispatch [event-id
|
||||
{:id transaction-id
|
||||
:hashes hashes}])))))
|
||||
|
||||
(h/deftest-event :wallet/select-from-account
|
||||
[event-id dispatch]
|
||||
(let [stack-id :screen/stack
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- transaction-title
|
||||
[{:keys [token-display-name amount account route to-network image-url transaction-type
|
||||
|
@ -238,6 +237,7 @@
|
|||
bridge-to-chain-id]))
|
||||
loading-suggested-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
transaction-for-signing (rf/sub [:wallet/wallet-send-transaction-for-signing])
|
||||
from-account-props {:customization-color account-color
|
||||
:size 32
|
||||
:emoji (:emoji account)
|
||||
|
@ -268,17 +268,21 @@
|
|||
:transaction-type transaction-type}]
|
||||
(when (and (not loading-suggested-routes?) route (seq route))
|
||||
[standard-auth/slide-button
|
||||
{:keycard-supported? true
|
||||
:size :size-48
|
||||
:track-text (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/slide-to-bridge)
|
||||
(i18n/label :t/slide-to-send))
|
||||
:container-style {:z-index 2}
|
||||
{:keycard-supported? (get-in transaction-for-signing
|
||||
[:signingDetails :signOnKeycard])
|
||||
:size :size-48
|
||||
:track-text (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/slide-to-bridge)
|
||||
(i18n/label :t/slide-to-send))
|
||||
:container-style {:z-index 2}
|
||||
:disabled? (not transaction-for-signing)
|
||||
:customization-color account-color
|
||||
:on-auth-success #(rf/dispatch
|
||||
[:wallet/send-transaction
|
||||
(security/safe-unmask-data %)])
|
||||
:auth-button-label (i18n/label :t/confirm)}])]
|
||||
:on-auth-success
|
||||
(fn [data]
|
||||
(rf/dispatch
|
||||
[:wallet/prepare-signatures-for-transactions
|
||||
:send data]))
|
||||
:auth-button-label (i18n/label :t/confirm)}])]
|
||||
:gradient-cover? true
|
||||
:customization-color (:color account)}
|
||||
[rn/view
|
||||
|
|
|
@ -303,3 +303,9 @@
|
|||
(defn bridge-disabled?
|
||||
[token-symbol]
|
||||
(not (constants/bridge-assets token-symbol)))
|
||||
|
||||
(defn signature-rsv
|
||||
[signature]
|
||||
{:r (subs signature 0 64)
|
||||
:s (subs signature 64 128)
|
||||
:v (subs signature 128 130)})
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
(ns status-im.contexts.wallet.swap.events
|
||||
(:require [native-module.core :as native-module]
|
||||
[re-frame.core :as rf]
|
||||
(:require [re-frame.core :as rf]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[status-im.contexts.wallet.sheets.network-selection.view :as network-selection]
|
||||
[status-im.contexts.wallet.swap.utils :as swap-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.number :as number]))
|
||||
|
@ -151,10 +148,9 @@
|
|||
:disabledFromChainIDs disabled-from-chain-ids
|
||||
:disabledToChainIDs disabled-to-chain-ids
|
||||
:gasFeeMode gas-rates
|
||||
:fromLockedAmount from-locked-amount}
|
||||
amount-in (assoc :amountIn amount-in-hex)
|
||||
amount-out (assoc :amountOut amount-out-hex))]]
|
||||
|
||||
:fromLockedAmount from-locked-amount
|
||||
:amountOut (or amount-out-hex "0x0")}
|
||||
amount-in (assoc :amountIn amount-in-hex))]]
|
||||
(when-let [amount (or amount-in amount-out)]
|
||||
{:db (update-in db
|
||||
[:wallet :ui :swap]
|
||||
|
@ -270,150 +266,21 @@
|
|||
(fn [{:keys [db]}]
|
||||
{:db (update-in db [:wallet :ui] dissoc :swap)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/swap-transaction
|
||||
(fn [{:keys [db]} [sha3-pwd]]
|
||||
(let [wallet-address (get-in db
|
||||
[:wallet
|
||||
:current-viewing-account-address])
|
||||
{:keys [asset-to-pay asset-to-receive
|
||||
swap-proposal network amount
|
||||
approval-transaction-id
|
||||
max-slippage]} (get-in db [:wallet :ui :swap])
|
||||
transactions (get-in db [:wallet :transactions])
|
||||
approval-transaction (when approval-transaction-id
|
||||
(get transactions approval-transaction-id))
|
||||
already-approved? (and approval-transaction
|
||||
(= (:status approval-transaction)
|
||||
:confirmed))
|
||||
approval-required? (and (:approval-required swap-proposal)
|
||||
(not already-approved?))
|
||||
multi-transaction-type constants/multi-transaction-type-swap
|
||||
swap-chain-id (:chain-id network)
|
||||
token-id-from (:symbol asset-to-pay)
|
||||
token-id-to (:symbol asset-to-receive)
|
||||
erc20-transfer? (and asset-to-pay (not= token-id-from "ETH"))
|
||||
eth-transfer? (and asset-to-pay (not erc20-transfer?))
|
||||
token-address (when erc20-transfer?
|
||||
(get-in asset-to-pay
|
||||
[:balances-per-chain swap-chain-id
|
||||
:address]))
|
||||
data (when erc20-transfer?
|
||||
(native-module/encode-transfer
|
||||
(address/normalized-hex wallet-address)
|
||||
(:amount-in swap-proposal)))
|
||||
transaction-paths (if approval-required?
|
||||
[(utils/approval-path
|
||||
{:route swap-proposal
|
||||
:token-address token-address
|
||||
:from-address wallet-address
|
||||
:to-address wallet-address})]
|
||||
[(utils/transaction-path
|
||||
{:to-address wallet-address
|
||||
:from-address wallet-address
|
||||
:route swap-proposal
|
||||
:token-address token-address
|
||||
:token-id-from token-id-from
|
||||
:token-id-to token-id-to
|
||||
:data data
|
||||
:slippage-percentage max-slippage
|
||||
:eth-transfer? eth-transfer?})])
|
||||
request-params [(utils/multi-transaction-command
|
||||
{:from-address wallet-address
|
||||
:to-address wallet-address
|
||||
:from-asset token-id-from
|
||||
:to-asset (if approval-required?
|
||||
token-id-from
|
||||
token-id-to)
|
||||
:amount-out (if eth-transfer?
|
||||
(:amount-out swap-proposal)
|
||||
"0x0")
|
||||
:multi-transaction-type
|
||||
multi-transaction-type})
|
||||
transaction-paths
|
||||
sha3-pwd]]
|
||||
(log/info "multi transaction called")
|
||||
{:json-rpc/call [{:method "wallet_createMultiTransaction"
|
||||
:params request-params
|
||||
:on-success (fn [result]
|
||||
(when result
|
||||
(let [receive-token-decimals (:decimals asset-to-receive)
|
||||
amount-out (:amount-out swap-proposal)
|
||||
receive-amount
|
||||
(when amount-out
|
||||
(-> amount-out
|
||||
(number/hex->whole receive-token-decimals)
|
||||
(money/to-fixed receive-token-decimals)))]
|
||||
(rf/dispatch [:centralized-metrics/track
|
||||
(if approval-required?
|
||||
:metric/swap-approval-execution-start
|
||||
:metric/swap-transaction-execution-start)
|
||||
(cond-> {:network swap-chain-id
|
||||
:pay_token token-id-from}
|
||||
(not approval-required?)
|
||||
(assoc :receive_token token-id-to))])
|
||||
(rf/dispatch [:wallet.swap/add-authorized-transaction
|
||||
(cond-> {:transaction result
|
||||
:approval-transaction?
|
||||
approval-required?}
|
||||
(not approval-required?)
|
||||
(assoc :swap-data
|
||||
{:pay-token-symbol token-id-from
|
||||
:pay-amount amount
|
||||
:receive-token-symbol token-id-to
|
||||
:receive-amount receive-amount
|
||||
:swap-chain-id swap-chain-id}))])
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:dismiss-modal
|
||||
(if approval-required?
|
||||
:screen/wallet.swap-set-spending-cap
|
||||
:screen/wallet.swap-confirmation)])
|
||||
(when-not approval-required?
|
||||
(rf/dispatch [:wallet/end-swap-flow])
|
||||
(debounce/debounce-and-dispatch
|
||||
[:toasts/upsert
|
||||
{:id :swap-transaction-pending
|
||||
:icon :i/info
|
||||
:type :neutral
|
||||
:text (i18n/label :t/swapping-to
|
||||
{:pay-amount amount
|
||||
:pay-token-symbol token-id-from
|
||||
:receive-token-symbol token-id-to
|
||||
:receive-amount receive-amount})}]
|
||||
500)))))
|
||||
:on-error (fn [error]
|
||||
(rf/dispatch [:centralized-metrics/track
|
||||
(if approval-required?
|
||||
:metric/swap-approval-execution-failed
|
||||
:metric/swap-transaction-execution-failed)
|
||||
(cond-> {:network swap-chain-id
|
||||
:error error
|
||||
:pay_token token-id-from}
|
||||
(not approval-required?)
|
||||
(assoc :receive_token token-id-to))])
|
||||
(log/error "failed swap transaction"
|
||||
{:event :wallet/swap-transaction
|
||||
:error error
|
||||
:params request-params})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :swap-transaction-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]})))
|
||||
|
||||
(rf/reg-event-fx :wallet.swap/add-authorized-transaction
|
||||
(fn [{:keys [db]} [{:keys [transaction swap-data approval-transaction?]}]]
|
||||
(let [transactions (get-in db [:wallet :transactions] {})
|
||||
transaction-batch-id (:id transaction)
|
||||
transaction-hashes (:hashes transaction)
|
||||
transaction-ids (flatten (vals transaction-hashes))
|
||||
(fn [{:keys [db]} [{:keys [sent-transactions swap-data approval-transaction?]}]]
|
||||
(let [wallet-transactions (get-in db [:wallet :transactions] {})
|
||||
transactions (utils/transactions->hash-to-transaction-map sent-transactions)
|
||||
transaction-ids (->> transactions
|
||||
vals
|
||||
(map :hash))
|
||||
transaction-id (first transaction-ids)
|
||||
transaction-details (cond-> (send-utils/map-multitransaction-by-ids transaction-batch-id
|
||||
transaction-hashes)
|
||||
transaction-details (cond-> transactions
|
||||
:always (assoc-in [transaction-id :tx-type] :swap)
|
||||
swap-data (assoc-in [transaction-id :swap-data] swap-data))
|
||||
swap-transaction-ids (get-in db [:wallet :swap-transaction-ids])]
|
||||
{:db (cond-> db
|
||||
:always (assoc-in [:wallet :transactions]
|
||||
(merge transactions transaction-details))
|
||||
(merge wallet-transactions transaction-details))
|
||||
:always (assoc-in [:wallet :ui :swap :transaction-ids] transaction-ids)
|
||||
approval-transaction? (assoc-in [:wallet :ui :swap :approval-transaction-id]
|
||||
transaction-id)
|
||||
|
@ -463,7 +330,8 @@
|
|||
(not transaction-confirmed?)
|
||||
(assoc :db (update-in db [:wallet :ui :swap] dissoc :approval-transaction-id)))))))
|
||||
|
||||
(rf/reg-event-fx :wallet.swap/swap-transaction-update
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/swap-transaction-update
|
||||
(fn [{:keys [db]} [{:keys [tx-hash status]}]]
|
||||
(let [{:keys [pay-amount pay-token-symbol
|
||||
receive-amount receive-token-symbol
|
||||
|
@ -494,7 +362,8 @@
|
|||
:receive-amount receive-amount})
|
||||
(i18n/label :t/swap-failed))}]]]}))))
|
||||
|
||||
(rf/reg-event-fx :wallet.swap/flip-assets
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/flip-assets
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [asset-to-pay asset-to-receive
|
||||
swap-proposal amount network]} (get-in db [:wallet :ui :swap])
|
||||
|
@ -528,14 +397,169 @@
|
|||
:previous_token (:symbol asset-to-receive)
|
||||
:new_token (:symbol asset-to-pay)}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/end-swap-flow
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/set-sign-transactions-callback-fx
|
||||
(fn [{:keys [db]} [callback-fx]]
|
||||
{:db (assoc-in db [:wallet :ui :swap :sign-transactions-callback-fx] callback-fx)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/approve
|
||||
(fn [{:keys [db]}]
|
||||
(let [launch-screen (get-in db [:wallet :ui :swap :launch-screen])
|
||||
address (get-in db [:wallet :current-viewing-account-address])]
|
||||
{:fx [(when (= launch-screen :wallet-stack)
|
||||
[:dispatch [:wallet/navigate-to-account-within-stack address]])
|
||||
(let [last-request-uuid (get-in db [:wallet :ui :swap :last-request-uuid])
|
||||
max-slippage (get-in db [:wallet :ui :swap :max-slippage])]
|
||||
{:fx [[:dispatch
|
||||
[:wallet/build-transactions-from-route
|
||||
{:request-uuid last-request-uuid
|
||||
:slippage max-slippage}]]
|
||||
[:dispatch
|
||||
[:wallet.swap/set-sign-transactions-callback-fx
|
||||
[:dispatch [:open-modal :screen/wallet.swap-set-spending-cap]]]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/review-swap
|
||||
(fn [{:keys [db]}]
|
||||
(let [last-request-uuid (get-in db [:wallet :ui :swap :last-request-uuid])
|
||||
max-slippage (get-in db [:wallet :ui :swap :max-slippage])]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :ui :swap] dissoc :transaction-for-signing))
|
||||
:fx [[:dispatch
|
||||
[:wallet/build-transactions-from-route
|
||||
{:request-uuid last-request-uuid
|
||||
:slippage max-slippage}]]
|
||||
[:dispatch
|
||||
[:navigate-to-within-stack
|
||||
[:screen/wallet.swap-confirmation
|
||||
:screen/wallet.setup-swap]]]]})))
|
||||
|
||||
(defn transaction-approval-required?
|
||||
[transactions {:keys [swap-proposal approval-transaction-id]}]
|
||||
(let [approval-transaction (when approval-transaction-id
|
||||
(get transactions approval-transaction-id))
|
||||
already-approved? (and approval-transaction
|
||||
(= (:status approval-transaction)
|
||||
:confirmed))]
|
||||
(and (:approval-required swap-proposal)
|
||||
(not already-approved?))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/mark-as-pending
|
||||
(fn [{:keys [db]} [transaction-id]]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :transactions transaction-id :status] :pending)
|
||||
(assoc-in [:wallet :ui :swap :approval-transaction-id] transaction-id))}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/transaction-success
|
||||
(fn [{:keys [db]} [sent-transactions]]
|
||||
(let [transactions (get-in db [:wallet :transactions])
|
||||
{:keys [swap-proposal
|
||||
asset-to-pay
|
||||
asset-to-receive
|
||||
network
|
||||
amount]
|
||||
:as swap} (get-in db [:wallet :ui :swap])
|
||||
swap-chain-id (:chain-id network)
|
||||
token-id-from (:symbol asset-to-pay)
|
||||
token-id-to (:symbol asset-to-receive)
|
||||
receive-token-decimals (:decimals asset-to-receive)
|
||||
amount-out (:amount-out swap-proposal)
|
||||
receive-amount (when amount-out
|
||||
(-> amount-out
|
||||
(number/hex->whole receive-token-decimals)
|
||||
(money/to-fixed receive-token-decimals)))
|
||||
approval-required? (transaction-approval-required? transactions swap)]
|
||||
{:fx [[:dispatch
|
||||
[:centralized-metrics/track
|
||||
(if approval-required?
|
||||
:metric/swap-approval-execution-start
|
||||
:metric/swap-transaction-execution-start)
|
||||
(cond-> {:network swap-chain-id
|
||||
:pay_token token-id-from}
|
||||
(not approval-required?)
|
||||
(assoc :receive_token token-id-to))]]
|
||||
[:dispatch
|
||||
[:wallet.swap/add-authorized-transaction
|
||||
(cond-> {:sent-transactions sent-transactions
|
||||
:approval-transaction? approval-required?}
|
||||
(not approval-required?)
|
||||
(assoc :swap-data
|
||||
{:pay-token-symbol token-id-from
|
||||
:pay-amount amount
|
||||
:receive-token-symbol token-id-to
|
||||
:receive-amount receive-amount
|
||||
:swap-chain-id swap-chain-id}))]]
|
||||
(when approval-required?
|
||||
;; dismiss the spending cap dialog if the transaction needs to be approved
|
||||
[:dispatch [:dismiss-modal :screen/wallet.swap-set-spending-cap]])
|
||||
(when approval-required?
|
||||
[:dispatch [:wallet.swap/mark-as-pending (-> sent-transactions first :hash)]])
|
||||
(when-not approval-required?
|
||||
;; just end the whole transaction flow if no approval needed
|
||||
[:dispatch [:wallet.swap/end-transaction-flow]])
|
||||
(when-not approval-required?
|
||||
[:dispatch-later
|
||||
{:ms 500
|
||||
:dispatch [:toasts/upsert
|
||||
{:id :swap-transaction-pending
|
||||
:icon :i/info
|
||||
:type :neutral
|
||||
:text (i18n/label :t/swapping-to
|
||||
{:pay-amount amount
|
||||
:pay-token-symbol token-id-from
|
||||
:receive-token-symbol token-id-to
|
||||
:receive-amount receive-amount})}]}])]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/transaction-failure
|
||||
(fn [{:keys [db]} [{:keys [details] :as error}]]
|
||||
(let [transactions (get-in db [:wallet :transactions])
|
||||
{:keys [asset-to-pay
|
||||
asset-to-receive
|
||||
network]
|
||||
:as swap} (get-in db [:wallet :ui :swap])
|
||||
swap-chain-id (:chain-id network)
|
||||
token-id-from (:symbol asset-to-pay)
|
||||
token-id-to (:symbol asset-to-receive)
|
||||
approval-required? (transaction-approval-required? transactions swap)]
|
||||
{:fx [[:centralized-metrics/track
|
||||
(if approval-required?
|
||||
:metric/swap-approval-execution-failed
|
||||
:metric/swap-transaction-execution-failed)
|
||||
(cond-> {:network swap-chain-id
|
||||
:error error
|
||||
:pay_token token-id-from}
|
||||
(not approval-required?)
|
||||
(assoc :receive_token token-id-to))]
|
||||
[:dispatch [:wallet.swap/end-transaction-flow]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:id :send-transaction-error
|
||||
:type :negative
|
||||
:text (or details "An error occured")}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/clean-up-transaction-flow
|
||||
(fn [{:keys [db]}]
|
||||
(let [transactions (get-in db [:wallet :transactions])
|
||||
swap (get-in db [:wallet :ui :swap])
|
||||
approval-required? (transaction-approval-required? transactions swap)]
|
||||
{:db (update-in db [:wallet :ui] dissoc :swap)
|
||||
:fx [[:dispatch
|
||||
[:dismiss-modal
|
||||
(if approval-required?
|
||||
:screen/wallet.swap-set-spending-cap
|
||||
:screen/wallet.swap-confirmation)]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet.swap/end-transaction-flow
|
||||
(fn [{:keys [db]}]
|
||||
(let [address (get-in db [:wallet :current-viewing-account-address])]
|
||||
{:fx [[:dispatch [:wallet/navigate-to-account-within-stack address]]
|
||||
[:dispatch [:wallet/fetch-activities-for-current-account]]
|
||||
[:dispatch [:wallet/select-account-tab :activity]]]})))
|
||||
[:dispatch [:wallet/select-account-tab :activity]]
|
||||
[:dispatch-later
|
||||
[{:ms 20
|
||||
:dispatch [:wallet.swap/clean-up-transaction-flow]}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet.swap/start-from-account
|
||||
(fn [{:keys [db]} [account]]
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
[status-im.contexts.wallet.swap.set-spending-cap.style :as style]
|
||||
[utils.address :as address-utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- swap-title
|
||||
[]
|
||||
|
@ -221,9 +220,8 @@
|
|||
(let [loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
on-auth-success (rn/use-callback #(rf/dispatch
|
||||
[:wallet/swap-transaction
|
||||
(security/safe-unmask-data %)]))]
|
||||
on-auth-success (rn/use-callback
|
||||
#(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap %]))]
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-sign)
|
||||
|
|
|
@ -95,8 +95,10 @@
|
|||
:subtitle (str max-slippage "%")
|
||||
:subtitle-icon :i/edit
|
||||
:size :small
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content slippage-settings/view}])}]]))
|
||||
:on-press (fn []
|
||||
(when-not loading-swap-proposal?
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content slippage-settings/view}])))}]]))
|
||||
|
||||
(defn- pay-token-input
|
||||
[{:keys [input-state on-max-press on-input-focus on-token-press on-approve-press input-focused?]}]
|
||||
|
@ -195,7 +197,8 @@
|
|||
:approve)
|
||||
:token-value approval-label-token-value
|
||||
:button-props (merge {:on-press on-approve-press}
|
||||
(when error-response
|
||||
(when (or loading-swap-proposal?
|
||||
error-response)
|
||||
{:disabled? true}))
|
||||
:customization-color account-color
|
||||
:token-symbol pay-token-symbol}}]))
|
||||
|
@ -361,9 +364,7 @@
|
|||
(not pay-input-error?))
|
||||
on-review-swap-press (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/wallet.swap-confirmation
|
||||
:screen/wallet.setup-swap]])))
|
||||
(rf/dispatch [:wallet.swap/review-swap])))
|
||||
on-press (rn/use-callback
|
||||
(fn [c]
|
||||
(let
|
||||
|
@ -492,7 +493,7 @@
|
|||
:on-max-press on-max-press
|
||||
:input-focused? pay-input-focused?
|
||||
:on-token-press #(rf/dispatch [:show-bottom-sheet {:content pay-token-bottom-sheet}])
|
||||
:on-approve-press #(rf/dispatch [:open-modal :screen/wallet.swap-set-spending-cap])
|
||||
:on-approve-press #(rf/dispatch [:wallet.swap/approve])
|
||||
:on-input-focus (fn []
|
||||
(when platform/android? (rf/dispatch [:dismiss-keyboard]))
|
||||
(set-pay-input-focused? true))}]
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
[status-im.contexts.wallet.swap.swap-confirmation.style :as style]
|
||||
[utils.address :as address-utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- on-close-action
|
||||
[]
|
||||
|
@ -165,22 +164,23 @@
|
|||
|
||||
(defn- slide-button
|
||||
[]
|
||||
(let [loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
account-color (:color account)
|
||||
on-auth-success (rn/use-callback (fn [data]
|
||||
(rf/dispatch [:wallet/stop-get-swap-proposal])
|
||||
(rf/dispatch [:wallet/swap-transaction
|
||||
(security/safe-unmask-data data)])))]
|
||||
(let [loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||
transaction-for-signing (rf/sub [:wallet/swap-transaction-for-signing])
|
||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
account-color (:color account)]
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-swap)
|
||||
:container-style {:z-index 2}
|
||||
:customization-color account-color
|
||||
:disabled? (or loading-swap-proposal? (not swap-proposal))
|
||||
:disabled? (or loading-swap-proposal?
|
||||
(not swap-proposal)
|
||||
(not transaction-for-signing))
|
||||
:auth-button-label (i18n/label :t/confirm)
|
||||
:on-auth-success on-auth-success}]))
|
||||
:on-auth-success (fn [data]
|
||||
(rf/dispatch [:wallet/stop-get-swap-proposal])
|
||||
(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap data]))}]))
|
||||
|
||||
(defn footer
|
||||
[]
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
(ns status-im.contexts.wallet.swap.swap-proposal.style)
|
||||
|
||||
(def container
|
||||
{:flex 1})
|
|
@ -1,27 +0,0 @@
|
|||
(ns status-im.contexts.wallet.swap.swap-proposal.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.wallet.sheets.slippage-settings.view :as slippage-settings]
|
||||
[status-im.contexts.wallet.swap.swap-proposal.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [max-slippage (rf/sub [:wallet/swap-max-slippage])]
|
||||
[rn/view {:style style/container}
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content slippage-settings/view}])}
|
||||
(str "Edit Slippage: " max-slippage "%")]
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/wallet.swap-confirmation :screen/wallet.swap-propasal]])}
|
||||
"Swap confirmation"]
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:open-modal :screen/wallet.swap-set-spending-cap])}
|
||||
"Set spending cap"]
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/wallet.setup-swap :screen/wallet.swap-propasal]])}
|
||||
"Setup swap"]]))
|
|
@ -1,63 +1,8 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.utils.rpc
|
||||
(:require [oops.core :as oops]
|
||||
[promesa.core :as promesa]
|
||||
(:require [promesa.core :as promesa]
|
||||
[status-im.common.json-rpc.events :as rpc-events]
|
||||
[status-im.constants :as constants]
|
||||
[utils.hex :as hex]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn wallet-build-transaction
|
||||
[chain-id tx]
|
||||
(promesa/let [res (rpc-events/call-async :wallet_buildTransaction true chain-id tx)]
|
||||
{:message-to-sign (oops/oget res :messageToSign)
|
||||
:tx-args (oops/oget res :txArgs)}))
|
||||
|
||||
(defn wallet-build-raw-transaction
|
||||
[chain-id tx-args signature]
|
||||
(-> (rpc-events/call-async "wallet_buildRawTransaction"
|
||||
true
|
||||
chain-id
|
||||
(transforms/js-stringify tx-args 0)
|
||||
signature)
|
||||
(promesa/then #(oops/oget % "rawTx"))))
|
||||
|
||||
(defn wallet-send-transaction-with-signature
|
||||
[chain-id tx-args signature]
|
||||
(rpc-events/call-async "wallet_sendTransactionWithSignature"
|
||||
true
|
||||
chain-id
|
||||
constants/transaction-pending-type-wallet-connect-transfer
|
||||
(transforms/js-stringify tx-args 0)
|
||||
signature))
|
||||
|
||||
(defn wallet-sign-message
|
||||
[message address password]
|
||||
(-> (rpc-events/call-async "wallet_signMessage"
|
||||
true
|
||||
message
|
||||
address
|
||||
password)
|
||||
(promesa/then hex/normalize-hex)))
|
||||
|
||||
(defn wallet-hash-message-eip-191
|
||||
[message]
|
||||
(rpc-events/call-async "wallet_hashMessageEIP191" true message))
|
||||
|
||||
(defn wallet-safe-sign-typed-data
|
||||
[data address password chain-id legacy?]
|
||||
(rpc-events/call-async "wallet_safeSignTypedDataForDApps"
|
||||
true
|
||||
data
|
||||
address
|
||||
password
|
||||
chain-id
|
||||
legacy?))
|
||||
|
||||
(defn wallet-get-suggested-fees
|
||||
[chain-id]
|
||||
(-> (rpc-events/call-async "wallet_getSuggestedFees" true chain-id)
|
||||
(promesa/then transforms/js->clj)))
|
||||
|
||||
(defn wallet-disconnect-persisted-session
|
||||
[topic]
|
||||
(rpc-events/call-async "wallet_disconnectWalletConnectSession" true topic))
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[promesa.core :as promesa]
|
||||
[status-im.contexts.wallet.rpc :as wallet-rpc]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.rpc :as rpc]
|
||||
[utils.hex :as hex]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
|
@ -19,6 +19,6 @@
|
|||
|
||||
(defn personal-sign
|
||||
[password address data]
|
||||
(-> (rpc/wallet-hash-message-eip-191 data)
|
||||
(promesa/then #(rpc/wallet-sign-message % address password))
|
||||
(-> (wallet-rpc/hash-message-eip-191 data)
|
||||
(promesa/then #(wallet-rpc/sign-message % address password))
|
||||
(promesa/then hex/prefix-hex)))
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
[native-module.core :as native-module]
|
||||
[promesa.core :as promesa]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.rpc :as wallet-rpc]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.rpc :as rpc]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.rpc :as wallet-connect-rpc]
|
||||
[utils.money :as money]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
|
@ -119,16 +120,17 @@
|
|||
"Formats and builds the incoming transaction, adding the missing properties and returning the final
|
||||
transaction, along with the transaction hash and the suggested fees"
|
||||
[tx chain-id tx-priority]
|
||||
(promesa/let [suggested-fees (rpc/wallet-get-suggested-fees chain-id)
|
||||
(promesa/let [suggested-fees (wallet-rpc/get-suggested-fees chain-id)
|
||||
{:keys [tx-args message-to-sign]} (->>
|
||||
(prepare-transaction-fees tx
|
||||
tx-priority
|
||||
suggested-fees)
|
||||
prepare-transaction-for-rpc
|
||||
(rpc/wallet-build-transaction chain-id))
|
||||
estimated-time (rpc/wallet-get-transaction-estimated-time
|
||||
chain-id
|
||||
(:maxPriorityFeePerGas suggested-fees))]
|
||||
(wallet-rpc/build-transaction
|
||||
chain-id))
|
||||
estimated-time (wallet-connect-rpc/wallet-get-transaction-estimated-time
|
||||
chain-id
|
||||
(:maxPriorityFeePerGas suggested-fees))]
|
||||
{:tx-args tx-args
|
||||
:tx-hash message-to-sign
|
||||
:suggested-fees suggested-fees
|
||||
|
@ -137,15 +139,15 @@
|
|||
(defn sign-transaction
|
||||
[password address tx-hash tx-args chain-id]
|
||||
(promesa/let
|
||||
[signature (rpc/wallet-sign-message tx-hash address password)
|
||||
raw-tx (rpc/wallet-build-raw-transaction chain-id tx-args signature)]
|
||||
[signature (wallet-rpc/sign-message tx-hash address password)
|
||||
raw-tx (wallet-rpc/build-raw-transaction chain-id tx-args signature)]
|
||||
raw-tx))
|
||||
|
||||
(defn send-transaction
|
||||
[password address tx-hash tx-args chain-id]
|
||||
(promesa/let
|
||||
[signature (rpc/wallet-sign-message tx-hash address password)
|
||||
tx (rpc/wallet-send-transaction-with-signature chain-id
|
||||
[signature (wallet-rpc/sign-message tx-hash address password)
|
||||
tx (wallet-rpc/send-transaction-with-signature chain-id
|
||||
tx-args
|
||||
signature)]
|
||||
tx))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.utils.typed-data
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.rpc :as wallet-rpc]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.rpc :as rpc]
|
||||
[utils.number :as number]))
|
||||
|
||||
(declare flatten-data)
|
||||
|
@ -88,7 +88,7 @@
|
|||
[password address data chain-id-eip155 version]
|
||||
(let [legacy? (= version :v1)
|
||||
chain-id (networks/eip155->chain-id chain-id-eip155)]
|
||||
(rpc/wallet-safe-sign-typed-data data
|
||||
(wallet-rpc/safe-sign-typed-data data
|
||||
address
|
||||
password
|
||||
chain-id
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
[status-im.contexts.wallet.swap.set-spending-cap.view :as wallet-swap-set-spending-cap]
|
||||
[status-im.contexts.wallet.swap.setup-swap.view :as wallet-swap-setup-swap]
|
||||
[status-im.contexts.wallet.swap.swap-confirmation.view :as wallet-swap-confirmation]
|
||||
[status-im.contexts.wallet.swap.swap-proposal.view :as wallet-swap-propasal]
|
||||
[status-im.contexts.wallet.wallet-connect.modals.send-transaction.view :as
|
||||
wallet-connect-send-transaction]
|
||||
[status-im.contexts.wallet.wallet-connect.modals.session-proposal.view :as
|
||||
|
@ -651,12 +650,6 @@
|
|||
:insets {:bottom? true}}
|
||||
:component wallet-swap-setup-swap/view}
|
||||
|
||||
{:name :screen/wallet.swap-propasal
|
||||
:metrics {:track? true
|
||||
:alias-id :wallet-swap.swap-proposal}
|
||||
:options {:insets {:top? true}}
|
||||
:component wallet-swap-propasal/view}
|
||||
|
||||
{:name :screen/wallet.swap-set-spending-cap
|
||||
:metrics {:track? true
|
||||
:alias-id :wallet-swap.set-spending-cap}
|
||||
|
|
|
@ -143,6 +143,11 @@
|
|||
:<- [:wallet/swap]
|
||||
:-> :loading-swap-proposal?)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/swap-transaction-for-signing
|
||||
:<- [:wallet/swap]
|
||||
:-> :transaction-for-signing)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/swap-proposal-amount-out
|
||||
:<- [:wallet/swap-proposal]
|
||||
|
|
|
@ -220,6 +220,11 @@
|
|||
:<- [:wallet/wallet-send]
|
||||
:-> :loading-suggested-routes?)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-transaction-for-signing
|
||||
:<- [:wallet/wallet-send]
|
||||
:-> :transaction-for-signing)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-suggested-routes
|
||||
:<- [:wallet/wallet-send]
|
||||
|
|
Loading…
Reference in New Issue