[Fix #7075] Show decoded topics and data as a clojure map in events properties
Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
parent
8e1da91ea0
commit
8f0955bea9
|
@ -606,6 +606,7 @@
|
||||||
{:permissions [:read]
|
{:permissions [:read]
|
||||||
:value :extensions/ethereum-transaction-receipt
|
:value :extensions/ethereum-transaction-receipt
|
||||||
:arguments {:value :string
|
:arguments {:value :string
|
||||||
|
:topics-hints :vector
|
||||||
:on-success :event
|
:on-success :event
|
||||||
:on-failure? :event}}
|
:on-failure? :event}}
|
||||||
'ethereum/await-transaction-receipt
|
'ethereum/await-transaction-receipt
|
||||||
|
@ -613,6 +614,7 @@
|
||||||
:value :extensions/ethereum-await-transaction-receipt
|
:value :extensions/ethereum-await-transaction-receipt
|
||||||
:arguments {:value :string
|
:arguments {:value :string
|
||||||
:interval :number
|
:interval :number
|
||||||
|
:topics-hints :vector
|
||||||
:on-success :event
|
:on-success :event
|
||||||
:on-failure? :event}}
|
:on-failure? :event}}
|
||||||
'ethereum/sign
|
'ethereum/sign
|
||||||
|
@ -662,7 +664,8 @@
|
||||||
'ethereum/logs-changes
|
'ethereum/logs-changes
|
||||||
{:permissions [:read]
|
{:permissions [:read]
|
||||||
:value :extensions/ethereum-logs-changes
|
:value :extensions/ethereum-logs-changes
|
||||||
:arguments {:id :string}}
|
:arguments {:id :string
|
||||||
|
:topics-hints :vector}}
|
||||||
'ethereum/cancel-filter
|
'ethereum/cancel-filter
|
||||||
{:permissions [:read]
|
{:permissions [:read]
|
||||||
:value :extensions/ethereum-cancel-filter
|
:value :extensions/ethereum-cancel-filter
|
||||||
|
|
|
@ -234,19 +234,60 @@
|
||||||
:on-failure on-failure}]
|
:on-failure on-failure}]
|
||||||
(wrap-with-resolution db json-rpc-args :to execute-send-transaction))))
|
(wrap-with-resolution db json-rpc-args :to execute-send-transaction))))
|
||||||
|
|
||||||
(defn- parse-log [{:keys [address transactionHash blockHash transactionIndex topics blockNumber logIndex removed data]}]
|
(defn- event-topic-enc [event params]
|
||||||
|
(let [eventid (str event "(" (string/join "," params) ")")]
|
||||||
|
(abi-spec/sha3 eventid)))
|
||||||
|
|
||||||
|
; Return a vector without indexed elements
|
||||||
|
(defn- get-no-indexed [X indexed]
|
||||||
|
(as-> (into [] (take (count X) (range))) $
|
||||||
|
(zipmap $ X)
|
||||||
|
(into [] (vals (apply dissoc $ indexed)))))
|
||||||
|
|
||||||
|
; Return a vector with indexed elements
|
||||||
|
(defn- get-indexed [X indexed]
|
||||||
|
(let [keys (into [] (take (count X) (range)))]
|
||||||
|
(mapv #((zipmap keys X) %) indexed)))
|
||||||
|
|
||||||
|
; Return the hint with the specified event (Topic0) from a vector of event hints given by the user
|
||||||
|
(defn- get-hint [hints first-topic]
|
||||||
|
(as-> hints $
|
||||||
|
(mapv #(event-topic-enc (% :event) (% :params)) $)
|
||||||
|
(.indexOf $ first-topic)
|
||||||
|
(get hints $)))
|
||||||
|
|
||||||
|
; Return a map with all data params decoded
|
||||||
|
(defn- decode-data [data hint]
|
||||||
|
(let [indexes (hint :indexed)
|
||||||
|
params (get-no-indexed (hint :params) indexes)
|
||||||
|
names (mapv keyword (get-no-indexed (hint :names) indexes)) ; Exclude indexed params and names from decode in data, these are decoded in topics
|
||||||
|
data-values (mapv (partial apply str) (partition 64 (string/replace-first data #"0x" "")))]
|
||||||
|
(zipmap names (mapv abi-spec/hex-to-value data-values params))))
|
||||||
|
|
||||||
|
; This assumes that Topic 0 is filtered and return a map with all topics decoded
|
||||||
|
(defn- decode-topics [topics hint]
|
||||||
|
(zipmap [:topic1 :topic2 :topic3] (mapv abi-spec/hex-to-value topics (get-indexed (hint :params) (hint :indexed))))) ; Solidity indexed event params may number up to 3 (max 4 Topics)
|
||||||
|
|
||||||
|
; Flatten the input of event provided by an developer of extensions and return a 1 depth vector
|
||||||
|
(defn- flatten-input [input]
|
||||||
|
(into [] (flatten input)))
|
||||||
|
|
||||||
|
(defn parse-log [events-hints {:keys [address transactionHash blockHash transactionIndex topics blockNumber logIndex removed data]}]
|
||||||
(merge {:data data
|
(merge {:data data
|
||||||
:topics topics
|
:topics topics
|
||||||
:address address
|
:address address
|
||||||
:removed removed}
|
:removed removed}
|
||||||
;; TODO parse data and topics, filter useless solidity first topic, aggregate as events ?
|
|
||||||
|
; filter useless topic 0 and decode topics
|
||||||
|
(when (and topics (seq events-hints)) {:topics (decode-topics (filterv #(not (= (first topics) %)) topics) (get-hint events-hints (first topics)))})
|
||||||
|
(when (and data (seq events-hints)) {:data (decode-data data (get-hint events-hints (first topics)))})
|
||||||
(when logIndex {:log-index (abi-spec/hex-to-number logIndex)})
|
(when logIndex {:log-index (abi-spec/hex-to-number logIndex)})
|
||||||
(when transactionIndex {:transaction-index (abi-spec/hex-to-number transactionIndex)})
|
(when transactionIndex {:transaction-index (abi-spec/hex-to-number transactionIndex)})
|
||||||
(when transactionHash {:transaction-hash transactionHash})
|
(when transactionHash {:transaction-hash transactionHash})
|
||||||
(when blockHash {:block-hash blockHash})
|
(when blockHash {:block-hash blockHash})
|
||||||
(when blockNumber {:block-number (abi-spec/hex-to-number blockNumber)})))
|
(when blockNumber {:block-number (abi-spec/hex-to-number blockNumber)})))
|
||||||
|
|
||||||
(defn- parse-receipt [m]
|
(defn- parse-receipt [events-hints m]
|
||||||
(when m
|
(when m
|
||||||
(let [{:keys [status transactionHash transactionIndex blockHash blockNumber from to cumulativeGasUsed gasUsed contractAddress logs logsBloom]} m]
|
(let [{:keys [status transactionHash transactionIndex blockHash blockNumber from to cumulativeGasUsed gasUsed contractAddress logs logsBloom]} m]
|
||||||
{:status (= 1 (abi-spec/hex-to-number status))
|
{:status (= 1 (abi-spec/hex-to-number status))
|
||||||
|
@ -259,27 +300,23 @@
|
||||||
:cumulative-gas-used (abi-spec/hex-to-number cumulativeGasUsed)
|
:cumulative-gas-used (abi-spec/hex-to-number cumulativeGasUsed)
|
||||||
:gas-used (abi-spec/hex-to-number gasUsed)
|
:gas-used (abi-spec/hex-to-number gasUsed)
|
||||||
:contract-address contractAddress
|
:contract-address contractAddress
|
||||||
:logs (map parse-log logs)
|
:logs (map #(parse-log events-hints %) logs)
|
||||||
:logs-bloom logsBloom})))
|
:logs-bloom logsBloom})))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions/ethereum-transaction-receipt
|
:extensions/ethereum-transaction-receipt
|
||||||
(fn [_ [_ _ {:keys [value] :as m}]]
|
(fn [_ [_ _ {:keys [value] :as m}]]
|
||||||
(rpc-call constants/web3-transaction-receipt [value] parse-receipt m)))
|
(rpc-call constants/web3-transaction-receipt [value] #(parse-receipt (flatten-input (:topics-hints m)) %) m)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions/ethereum-await-transaction-receipt
|
:extensions/ethereum-await-transaction-receipt
|
||||||
(fn [_ [_ _ {:keys [value interval on-success] :as m}]]
|
(fn [_ [_ _ {:keys [value interval on-success] :as m}]]
|
||||||
(let [id (atom nil)
|
(let [id (atom nil)
|
||||||
new-on-success (fn [o] (js/clearInterval @id) (on-success o))]
|
new-on-success (fn [o] (js/clearInterval @id) (on-success o))]
|
||||||
(reset! id (js/setInterval #(rpc-call constants/web3-transaction-receipt [value] parse-receipt
|
(reset! id (js/setInterval #(rpc-call constants/web3-transaction-receipt [value] (fn [result] (parse-receipt (flatten-input (:topics-hints m)) result))
|
||||||
(assoc m :on-success new-on-success)) interval))
|
(assoc m :on-success new-on-success)) interval))
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
(defn- event-topic-enc [event params]
|
|
||||||
(let [eventid (str event "(" (string/join "," params) ")")]
|
|
||||||
(abi-spec/sha3 eventid)))
|
|
||||||
|
|
||||||
(defn- types-mapping [type]
|
(defn- types-mapping [type]
|
||||||
(cond
|
(cond
|
||||||
(= "bool" type) :bool
|
(= "bool" type) :bool
|
||||||
|
@ -317,7 +354,8 @@
|
||||||
:address address
|
:address address
|
||||||
:topics (generate-topic topics)
|
:topics (generate-topic topics)
|
||||||
:blockhash block-hash}]]
|
:blockhash block-hash}]]
|
||||||
(rpc-call constants/web3-get-logs params #(map parse-log %) m)))
|
|
||||||
|
(rpc-call constants/web3-get-logs params (fn [results] (map #(parse-log (flatten-input (:topics m)) %) results)) m))) ; Get event-hints from the topics input given by the user
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions/ethereum-logs
|
:extensions/ethereum-logs
|
||||||
|
@ -368,7 +406,7 @@
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions/ethereum-logs-changes
|
:extensions/ethereum-logs-changes
|
||||||
(fn [_ [_ _ {:keys [id] :as m}]]
|
(fn [_ [_ _ {:keys [id] :as m}]]
|
||||||
(rpc-call constants/web3-get-filter-changes [(abi-spec/number-to-hex id)] #(map parse-log %) m)))
|
(rpc-call constants/web3-get-filter-changes [(abi-spec/number-to-hex id)] (fn [results] (map #(parse-log (flatten-input (:topics-hints m)) %) results)) m)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions/ethereum-cancel-filter
|
:extensions/ethereum-cancel-filter
|
||||||
|
|
Loading…
Reference in New Issue