mirror of
https://github.com/status-im/status-react.git
synced 2025-02-02 06:07:33 +00:00
[extensions] ethereum events
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
a42d4f60b3
commit
5ba5395d57
@ -139,7 +139,7 @@
|
||||
:parameters [{:id :keyword
|
||||
:type {:one-of #{:text :phone :password :number}}
|
||||
:placeholder :string
|
||||
:suggestions :view}]}
|
||||
:suggestions? :view}]}
|
||||
:hook
|
||||
(reify hooks/Hook
|
||||
(hook-in [_ id {:keys [description scope parameters preview short-preview on-send on-receive]} cofx]
|
||||
|
@ -16,13 +16,14 @@
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.utils.fx :as fx]))
|
||||
[status-im.utils.fx :as fx]
|
||||
status-im.extensions.ethereum))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::alert
|
||||
(fn [value] (js/alert value)))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
(handlers/register-handler-fx
|
||||
:alert
|
||||
(fn [_ [_ {:keys [value]}]]
|
||||
{::alert value}))
|
||||
@ -31,7 +32,7 @@
|
||||
::log
|
||||
(fn [value] (js/console.log value)))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
(handlers/register-handler-fx
|
||||
:log
|
||||
(fn [_ [_ {:keys [value]}]]
|
||||
{::log value}))
|
||||
@ -148,7 +149,7 @@
|
||||
'transaction-status {:value transactions/transaction-status :properties {:outgoing :string :tx-hash :string}}
|
||||
'asset-selector {:value transactions/choose-nft-asset-suggestion}
|
||||
'token-selector {:value transactions/choose-nft-token-suggestion}}
|
||||
:queries {'store/get {:value :store/get :arguments {:key :string}}
|
||||
:queries {'store/get {:value :store/get :arguments {:key :string}}
|
||||
'wallet/collectibles {:value :get-collectible-token :arguments {:token :string :symbol :string}}}
|
||||
:events {'alert
|
||||
{:permissions [:read]
|
||||
@ -191,30 +192,25 @@
|
||||
:arguments {:hash :string
|
||||
:on-success :event
|
||||
:on-failure? :event}}
|
||||
'ethereum/sign
|
||||
{:arguments
|
||||
{:account :string
|
||||
:message :string
|
||||
:on-result :event}}
|
||||
'ethereum/send-transaction
|
||||
{:arguments
|
||||
{:from :string
|
||||
:to :string
|
||||
:gas? :string
|
||||
:gas-price? :string
|
||||
:value? :string
|
||||
:data? :string
|
||||
:nonce? :string}}
|
||||
{:permissions [:read]
|
||||
:value :extensions/ethereum-send-transaction
|
||||
:arguments {:to :string
|
||||
:gas? :string
|
||||
:gas-price? :string
|
||||
:value? :string
|
||||
:method? :string
|
||||
:params? :vector
|
||||
:nonce? :string
|
||||
:on-result? :event}}
|
||||
'ethereum/call
|
||||
{:arguments
|
||||
{:from? :string
|
||||
:to :string
|
||||
:gas? :string
|
||||
:gas-price? :string
|
||||
:value? :string
|
||||
:data? :string
|
||||
:block :string}}}
|
||||
:hooks {:commands commands/command-hook}})
|
||||
{:permissions [:read]
|
||||
:value :extensions/ethereum-call
|
||||
:arguments {:to :string
|
||||
:method :string
|
||||
:params? :vector
|
||||
:on-result? :event}}}
|
||||
:hooks {:commands commands/command-hook}})
|
||||
|
||||
(defn read-extension [{:keys [value]}]
|
||||
(when (seq value)
|
||||
|
39
src/status_im/extensions/ethereum.cljs
Normal file
39
src/status_im/extensions/ethereum.cljs
Normal file
@ -0,0 +1,39 @@
|
||||
(ns status-im.extensions.ethereum
|
||||
(:require [status-im.utils.handlers :as handlers]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.models.wallet :as models.wallet]
|
||||
[status-im.utils.ethereum.abi-spec :as abi-spec]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.ui.screens.navigation :as navigation]))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:extensions/transaction-on-result
|
||||
(fn [cofx [_ on-result id result method]]
|
||||
(fx/merge cofx
|
||||
(when on-result
|
||||
{:dispatch (on-result {:error nil :result result})})
|
||||
(navigation/navigate-to-clean :wallet-transaction-sent nil))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:extensions/transaction-on-error
|
||||
(fn [{db :db} [_ on-result message]]
|
||||
(when on-result {:dispatch (on-result {:error message :result nil})})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:extensions/ethereum-send-transaction
|
||||
(fn [{db :db} [_ {:keys [method params on-result] :as arguments}]]
|
||||
(let [tx-object (assoc (select-keys arguments [:to :gas :gas-price :value :nonce])
|
||||
:data (when (and method params) (abi-spec/encode method params)))
|
||||
transaction (models.wallet/prepare-extension-transaction tx-object (:contacts/contacts db) on-result)]
|
||||
(models.wallet/open-modal-wallet-for-transaction db transaction tx-object))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:extensions/ethereum-call
|
||||
(fn [_ [_ {:keys [to method params on-result]}]]
|
||||
(let [tx-object {:to to :data (when method (abi-spec/encode method params))}]
|
||||
{:browser/call-rpc [{"jsonrpc" "2.0"
|
||||
"method" "eth_call"
|
||||
"params" [tx-object "latest"]}
|
||||
#(when on-result
|
||||
(re-frame/dispatch (on-result {:error %1 :result (when %2
|
||||
(get (js->clj %2) "result"))})))]})))
|
@ -63,7 +63,7 @@
|
||||
{:db (update-in db [:wallet :edit] build-edit key value)})
|
||||
|
||||
;; DAPP TRANSACTION -> SEND TRANSACTION
|
||||
(defn prepare-dapp-transaction [{{:keys [id method params]} :payload :as queued-transaction} contacts]
|
||||
(defn prepare-dapp-transaction [{{:keys [id method params]} :payload message-id :message-id} contacts]
|
||||
(let [{:keys [to value data gas gasPrice nonce]} (first params)
|
||||
contact (get contacts (utils.hex/normalize-hex to))]
|
||||
(cond-> {:id (str id)
|
||||
@ -72,7 +72,6 @@
|
||||
contact)
|
||||
:symbol :ETH
|
||||
:method method
|
||||
:dapp-transaction queued-transaction
|
||||
:to to
|
||||
:amount (money/bignumber (or value 0))
|
||||
:gas (cond
|
||||
@ -82,7 +81,34 @@
|
||||
(money/bignumber 21000))
|
||||
:gas-price (when gasPrice
|
||||
(money/bignumber gasPrice))
|
||||
:data data}
|
||||
:data data
|
||||
:on-result [:wallet.dapp/transaction-on-result message-id]
|
||||
:on-error [:wallet.dapp/transaction-on-error message-id]}
|
||||
nonce
|
||||
(assoc :nonce nonce))))
|
||||
|
||||
;; EXTENSION TRANSACTION -> SEND TRANSACTION
|
||||
(defn prepare-extension-transaction [params contacts on-result]
|
||||
(let [{:keys [to value data gas gasPrice nonce]} params
|
||||
contact (get contacts (utils.hex/normalize-hex to))]
|
||||
(cond-> {:id "extension-id"
|
||||
:to-name (or (when (nil? to)
|
||||
(i18n/label :t/new-contract))
|
||||
contact)
|
||||
:symbol :ETH
|
||||
:method constants/web3-send-transaction
|
||||
:to to
|
||||
:amount (money/bignumber (or value 0))
|
||||
:gas (cond
|
||||
gas
|
||||
(money/bignumber gas)
|
||||
(and value (empty? data))
|
||||
(money/bignumber 21000))
|
||||
:gas-price (when gasPrice
|
||||
(money/bignumber gasPrice))
|
||||
:data data
|
||||
:on-result [:extensions/transaction-on-result on-result]
|
||||
:on-error [:extensions/transaction-on-error on-result]}
|
||||
nonce
|
||||
(assoc :nonce nonce))))
|
||||
|
||||
@ -110,7 +136,7 @@
|
||||
[first_param second_param]
|
||||
[second_param first_param]))))
|
||||
|
||||
(defn web3-error-callback [fx {:keys [webview-bridge]} {:keys [message-id]} message]
|
||||
(defn web3-error-callback [fx {:keys [webview-bridge]} message-id message]
|
||||
(assoc fx :browser/send-to-bridge {:message {:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:error message}
|
||||
@ -131,15 +157,15 @@
|
||||
(= method constants/web3-send-transaction)
|
||||
(assoc :dispatch [:navigate-to-clean :wallet-transaction-sent])))
|
||||
|
||||
(defn discard-transaction
|
||||
(fx/defn discard-transaction
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [dapp-transaction]} (get-in db [:wallet :send-transaction])]
|
||||
(cond-> {:db (update db :wallet
|
||||
assoc
|
||||
:send-transaction {}
|
||||
:transactions-queue nil)}
|
||||
dapp-transaction
|
||||
(web3-error-callback db dapp-transaction "discarded"))))
|
||||
(let [{:keys [on-error]} (get-in db [:wallet :send-transaction])]
|
||||
(merge {:db (update db :wallet
|
||||
assoc
|
||||
:send-transaction {}
|
||||
:transactions-queue nil)}
|
||||
(when on-error
|
||||
{:dispatch (conj on-error "transaction was cancelled by user")}))))
|
||||
|
||||
(defn prepare-unconfirmed-transaction [db now hash]
|
||||
(let [transaction (get-in db [:wallet :send-transaction])]
|
||||
@ -157,7 +183,7 @@
|
||||
(dissoc :message-id :id :gas)))))
|
||||
|
||||
(defn handle-transaction-error [{:keys [db]} {:keys [code message]}]
|
||||
(let [{:keys [dapp-transaction]} (get-in db [:wallet :send-transaction])]
|
||||
(let [{:keys [on-error]} (get-in db [:wallet :send-transaction])]
|
||||
(case code
|
||||
|
||||
;;WRONG PASSWORD
|
||||
@ -165,16 +191,16 @@
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :send-transaction :wrong-password?] true))}
|
||||
|
||||
(cond-> (let [cofx {:db
|
||||
(-> db
|
||||
(assoc-in [:wallet :transactions-queue] nil)
|
||||
(assoc-in [:wallet :send-transaction] {}))
|
||||
:wallet/show-transaction-error
|
||||
message}]
|
||||
(navigation/navigate-back cofx))
|
||||
(merge (let [cofx {:db
|
||||
(-> db
|
||||
(assoc-in [:wallet :transactions-queue] nil)
|
||||
(assoc-in [:wallet :send-transaction] {}))
|
||||
:wallet/show-transaction-error
|
||||
message}]
|
||||
(navigation/navigate-back cofx))
|
||||
|
||||
dapp-transaction
|
||||
(web3-error-callback db dapp-transaction message)))))
|
||||
(when on-error
|
||||
{:dispatch (conj on-error message)})))))
|
||||
|
||||
(defn transform-data-for-message [{:keys [method] :as transaction}]
|
||||
(cond-> transaction
|
||||
@ -216,3 +242,17 @@
|
||||
(clear-error-message :balance-update)
|
||||
(assoc-in [:wallet :balance-loading?] true)
|
||||
(assoc :prices-loading? true))})))
|
||||
|
||||
(defn open-modal-wallet-for-transaction [db transaction tx-object]
|
||||
(let [{:keys [gas gas-price]} transaction
|
||||
{:keys [wallet-set-up-passed?]} (:account/account db)]
|
||||
{:db (assoc-in db [:wallet :send-transaction] transaction)
|
||||
:dispatch-n [[:update-wallet]
|
||||
(when-not gas
|
||||
[:wallet/update-estimated-gas tx-object])
|
||||
(when-not gas-price
|
||||
[:wallet/update-gas-price])
|
||||
[:navigate-to
|
||||
(if wallet-set-up-passed?
|
||||
:wallet-send-modal-stack
|
||||
:wallet-send-modal-stack-with-onboarding)]]}))
|
||||
|
@ -32,11 +32,12 @@
|
||||
(spec/def ::whisper-identity (spec/nilable string?))
|
||||
(spec/def ::method (spec/nilable string?))
|
||||
(spec/def ::tx-hash (spec/nilable string?))
|
||||
(spec/def ::dapp-transaction (spec/nilable any?))
|
||||
(spec/def ::on-result (spec/nilable any?))
|
||||
(spec/def ::on-error (spec/nilable any?))
|
||||
|
||||
(spec/def :wallet/send-transaction (allowed-keys
|
||||
:opt-un [::amount ::to ::to-name ::amount-error ::asset-error ::amount-text
|
||||
::password ::show-password-input? ::id ::from ::data ::nonce
|
||||
::camera-flashlight ::in-progress? ::dapp-transaction
|
||||
::camera-flashlight ::in-progress? ::on-result ::on-error
|
||||
::wrong-password? ::from-chat? ::symbol ::advanced?
|
||||
::gas ::gas-price ::whisper-identity ::method ::tx-hash]))
|
||||
|
@ -83,7 +83,7 @@
|
||||
(handlers/register-handler-fx
|
||||
::transaction-completed
|
||||
(fn [{:keys [db now] :as cofx} [_ {:keys [result error]}]]
|
||||
(let [{:keys [id method whisper-identity to symbol amount-text dapp-transaction]} (get-in db [:wallet :send-transaction])
|
||||
(let [{:keys [id method whisper-identity to symbol amount-text on-result]} (get-in db [:wallet :send-transaction])
|
||||
db' (assoc-in db [:wallet :send-transaction :in-progress?] false)]
|
||||
(if error
|
||||
;; ERROR
|
||||
@ -96,10 +96,8 @@
|
||||
(assoc-in [:wallet :transactions result]
|
||||
(models.wallet/prepare-unconfirmed-transaction db now result)))}
|
||||
|
||||
(if dapp-transaction
|
||||
(let [{:keys [message-id]} dapp-transaction
|
||||
webview (:webview-bridge db)]
|
||||
(models.wallet/dapp-complete-transaction (int id) result method message-id webview))
|
||||
(if on-result
|
||||
{:dispatch (conj on-result id result method)}
|
||||
{:dispatch [:send-transaction-message whisper-identity {:address to
|
||||
:asset (name symbol)
|
||||
:amount amount-text
|
||||
@ -111,6 +109,17 @@
|
||||
(fn [cofx _]
|
||||
(models.wallet/discard-transaction cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.dapp/transaction-on-result
|
||||
(fn [{db :db} [_ message-id id result method]]
|
||||
(let [webview (:webview-bridge db)]
|
||||
(models.wallet/dapp-complete-transaction (int id) result method message-id webview))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.dapp/transaction-on-error
|
||||
(fn [{db :db} [_ message-id message]]
|
||||
(models.wallet/web3-error-callback {} db message-id message)))
|
||||
|
||||
;; DAPP TRANSACTIONS QUEUE
|
||||
;; NOTE(andrey) We need this queue because dapp can send several transactions in a row, this is bad behaviour
|
||||
;; but we need to support it
|
||||
@ -126,19 +135,8 @@
|
||||
|
||||
;;SEND TRANSACTION
|
||||
(= method constants/web3-send-transaction)
|
||||
(let [{:keys [gas gas-price] :as transaction} (models.wallet/prepare-dapp-transaction
|
||||
queued-transaction (:contacts/contacts db))
|
||||
{:keys [wallet-set-up-passed?]} (:account/account db)]
|
||||
{:db (assoc-in db' [:wallet :send-transaction] transaction)
|
||||
:dispatch-n [[:update-wallet]
|
||||
(when-not gas
|
||||
[:wallet/update-estimated-gas (first params)])
|
||||
(when-not gas-price
|
||||
[:wallet/update-gas-price])
|
||||
[:navigate-to
|
||||
(if wallet-set-up-passed?
|
||||
:wallet-send-modal-stack
|
||||
:wallet-send-modal-stack-with-onboarding)]]})
|
||||
(let [transaction (models.wallet/prepare-dapp-transaction queued-transaction (:contacts/contacts db))]
|
||||
(models.wallet/open-modal-wallet-for-transaction db' transaction (first params)))
|
||||
|
||||
;;SIGN MESSAGE
|
||||
(= method constants/web3-personal-sign)
|
||||
@ -148,7 +146,8 @@
|
||||
{:id (str (or id message-id))
|
||||
:from address
|
||||
:data data
|
||||
:dapp-transaction queued-transaction
|
||||
:on-result [:wallet.dapp/transaction-on-result message-id]
|
||||
:on-error [:wallet.dapp/transaction-on-error message-id]
|
||||
:method method})]
|
||||
(navigation/navigate-to-cofx {:db db''} :wallet-sign-message-modal nil))
|
||||
{:db db'})))))))
|
||||
@ -181,9 +180,9 @@
|
||||
(handlers/register-handler-fx
|
||||
:wallet/discard-transaction-navigate-back
|
||||
(fn [cofx _]
|
||||
(-> cofx
|
||||
models.wallet/discard-transaction
|
||||
(assoc :dispatch [:navigate-back]))))
|
||||
(fx/merge cofx
|
||||
(navigation/navigate-back)
|
||||
(models.wallet/discard-transaction))))
|
||||
|
||||
(defn update-gas-price
|
||||
([db edit? success-event]
|
||||
|
Loading…
x
Reference in New Issue
Block a user