Skip to content

Commit

Permalink
[extensions] ethereum events
Browse files Browse the repository at this point in the history
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
  • Loading branch information
flexsurfer authored and jeluard committed Oct 19, 2018
1 parent 8395b2f commit f80e901
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 73 deletions.
2 changes: 1 addition & 1 deletion src/status_im/chat/commands/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
48 changes: 22 additions & 26 deletions src/status_im/extensions/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -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}))
Expand All @@ -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}))
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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)
Expand Down
39 changes: 39 additions & 0 deletions src/status_im/extensions/ethereum.cljs
Original file line number Diff line number Diff line change
@@ -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"))})))]})))
84 changes: 62 additions & 22 deletions src/status_im/models/wallet.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -72,7 +72,6 @@
contact)
:symbol :ETH
:method method
:dapp-transaction queued-transaction
:to to
:amount (money/bignumber (or value 0))
:gas (cond
Expand All @@ -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))))

Expand Down Expand Up @@ -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}
Expand All @@ -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])]
Expand All @@ -157,24 +183,24 @@
(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
constants/send-transaction-err-decrypt
{: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
Expand Down Expand Up @@ -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)]]}))
5 changes: 3 additions & 2 deletions src/status_im/ui/screens/wallet/send/db.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -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]))
43 changes: 21 additions & 22 deletions src/status_im/ui/screens/wallet/send/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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'})))))))
Expand Down Expand Up @@ -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]
Expand Down

0 comments on commit f80e901

Please sign in to comment.