Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
tbenr 2018-11-28 21:11:45 +01:00 committed by Julien Eluard
parent 08291a8396
commit 3070e1f8a6
No known key found for this signature in database
GPG Key ID: 6FD7DB5437FCBEF6
2 changed files with 73 additions and 31 deletions

View File

@ -366,6 +366,11 @@
:topics? :vector
:blockhash? :string
:on-result :event}}
'ethereum/resolve-ens
{:permissions [:read]
:value :extensions/ethereum-resolve-ens
:arguments {:name :string
:on-result :event}}
'ethereum/call
{:permissions [:read]
:value :extensions/ethereum-call

View File

@ -8,6 +8,8 @@
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.ethereum.abi-spec :as abi-spec]
[status-im.utils.fx :as fx]
[status-im.utils.ethereum.ens :as ens]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.handlers :as handlers]
[status-im.utils.money :as money]
[clojure.string :as string]
@ -27,6 +29,21 @@
(fn [{db :db} [_ on-result message]]
(when on-result {:dispatch (on-result {:error message :result nil})})))
(defn- wrap-with-resolution [db arguments address-keyword f]
"funtction responsible to resolve ens taken from argument
and call the specified function with resolved address"
(let [address (get arguments address-keyword)
first-address (if (vector? address) ;; currently we only support one ens for address
(first address)
address)]
(if (ens/is-valid-eth-name? first-address)
(let [{:keys [web3 network]} db
network-info (get-in db [:account/account :networks network])
chain (ethereum/network->chain-keyword network-info)
registry (get ens/ens-registries chain)]
(ens/get-addr web3 registry first-address #(f db (assoc arguments address-keyword %))))
(f db arguments))))
;; EXTENSION TRANSACTION -> SEND TRANSACTION
(defn prepare-extension-transaction [params contacts on-result]
(let [{:keys [to value data gas gasPrice nonce]} params
@ -52,29 +69,35 @@
nonce
(assoc :nonce nonce))))
(defn- execute-send-transaction [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 (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-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 (prepare-extension-transaction tx-object (:contacts/contacts db) on-result)]
(models.wallet/open-modal-wallet-for-transaction db transaction tx-object))))
(fn [{db :db} [_ _ arguments]]
(wrap-with-resolution db arguments :to execute-send-transaction)))
(defn- execute-ethcall [_ {:keys [to method params outputs 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"]}
#(let [result-str (when %2
(get (js->clj %2) "result"))
result (cond
(= "0x" result-str) nil
(and outputs result-str)
(abi-spec/decode (string/replace result-str #"0x" "") outputs)
:else result-str)]
(re-frame/dispatch (on-result (merge {:result result} (when %1 {:error %1})))))]}))
(handlers/register-handler-fx
:extensions/ethereum-call
(fn [_ [_ _ {:keys [to method params outputs 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"]}
#(let [result-str (when %2
(get (js->clj %2) "result"))
result (cond
(= "0x" result-str) nil
(and outputs result-str)
(abi-spec/decode (string/replace result-str #"0x" "") outputs)
:else result-str)]
(re-frame/dispatch (on-result (merge {:result result} (when %1 {:error %1})))))]})))
(fn [{db :db} [_ _ {:keys [to] :as arguments}]]
(wrap-with-resolution db arguments :to execute-ethcall)))
;; eth_getLogs implementation
@ -114,18 +137,32 @@
(re-matches #"^[0-9]+$" block) (str "0x" (abi-spec/number-to-hex block))
:else block))
(defn- execute-get-logs [_ {:keys [fromBlock toBlock address topics blockhash on-result]}]
(let [parsed-topics (mapv parse-topic topics)
args {:jsonrpc "2.0"
:method constants/web3-get-logs
:params [{:fromBlock (ensure-hex-bn fromBlock)
:toBlock (ensure-hex-bn toBlock)
:address address
:topics parsed-topics
:blockhash blockhash}]}
payload (types/clj->json args)]
(status/call-private-rpc payload #(let [{:keys [error result]} (types/json->clj %1)
response (merge {:result result} (when error {:error error}))]
(re-frame/dispatch (on-result response))))))
(handlers/register-handler-fx
:extensions/ethereum-logs
(fn [_ [_ _ {:keys [fromBlock toBlock address topics blockhash on-result]}]]
(let [parsed-topics (mapv parse-topic topics)
args {:jsonrpc "2.0"
:method constants/web3-get-logs
:params [{:fromBlock (ensure-hex-bn fromBlock)
:toBlock (ensure-hex-bn toBlock)
:address address
:topics parsed-topics
:blockhash blockhash}]}
payload (types/clj->json args)]
(status/call-private-rpc payload #(let [{:keys [error result]} (types/json->clj %1)
response (merge {:result result} (when error {:error error}))]
(re-frame/dispatch (on-result response)))))))
(fn [{db :db} [_ _ arguments]]
(wrap-with-resolution db arguments :address execute-get-logs)))
(handlers/register-handler-fx
:extensions/ethereum-resolve-ens
(fn [{db :db} [_ _ {:keys [name on-result] :as arguments}]]
(if (ens/is-valid-eth-name? name)
(let [{:keys [web3 network]} db
network-info (get-in db [:account/account :networks network])
chain (ethereum/network->chain-keyword network-info)
registry (get ens/ens-registries chain)]
(ens/get-addr web3 registry name #(re-frame/dispatch (on-result {:result %}))))
(re-frame/dispatch (on-result {:error (str "'" name "' is not a valid name")})))))