Fix WalletConnect transactions (#20608)
* fix: sign-transaction Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: sendTranasaction not working Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * ref: removing 0x from the signature Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * ref: tx data from responding to processing events Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: request dapp subscription Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: tx data bug Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> --------- Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>
This commit is contained in:
parent
e58e2209bb
commit
f51f52ec27
|
@ -282,6 +282,8 @@
|
|||
(def ^:const wallet-connect-session-proposal-event "session_proposal")
|
||||
(def ^:const wallet-connect-session-request-event "session_request")
|
||||
|
||||
(def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer")
|
||||
|
||||
(def ^:const dapp-permission-contact-code "contact-code")
|
||||
(def ^:const dapp-permission-web3 "web3")
|
||||
(def ^:const dapp-permission-qr-code "qr-code")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.effects
|
||||
(:require [cljs-bean.core :as bean]
|
||||
(:require
|
||||
[cljs-bean.core :as bean]
|
||||
[native-module.core :as native-module]
|
||||
[promesa.core :as promesa]
|
||||
[re-frame.core :as rf]
|
||||
|
@ -7,6 +8,7 @@
|
|||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core]
|
||||
[status-im.contexts.wallet.wallet-connect.transactions :as transactions]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as transforms]))
|
||||
|
@ -92,10 +94,24 @@
|
|||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/sign-transaction
|
||||
(fn [{:keys [password address chain-id tx on-success on-error]}]
|
||||
(-> (transactions/sign-transaction (security/safe-unmask-data password) address tx chain-id)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/send-transaction
|
||||
(fn [{:keys [password address chain-id tx on-success on-error]}]
|
||||
(-> (transactions/send-transaction (security/safe-unmask-data password) address tx chain-id)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/sign-typed-data
|
||||
(fn [{:keys [password address data version on-success on-error]}]
|
||||
(-> (wallet-connect-core/sign-typed-data version data address password)
|
||||
(-> (wallet-connect-core/sign-typed-data version data address (security/safe-unmask-data password))
|
||||
(promesa/then wallet-connect-core/extract-native-call-signature)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.processing-events
|
||||
(:require [native-module.core :as native-module]
|
||||
(:require [clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core]
|
||||
|
@ -45,7 +46,7 @@
|
|||
{:db (update-in db
|
||||
[:wallet-connect/current-request]
|
||||
assoc
|
||||
:address address
|
||||
:address (string/lower-case address)
|
||||
:raw-data raw-data
|
||||
:display-data (or parsed-data raw-data))})))
|
||||
|
||||
|
@ -57,7 +58,7 @@
|
|||
{:db (update-in db
|
||||
[:wallet-connect/current-request]
|
||||
assoc
|
||||
:address address
|
||||
:address (string/lower-case address)
|
||||
:raw-data raw-data
|
||||
:display-data (or parsed-data raw-data))})))
|
||||
|
||||
|
@ -68,12 +69,17 @@
|
|||
display-data (-> event
|
||||
clj->js
|
||||
(js/JSON.stringify nil 2))
|
||||
{:keys [to]} (-> event wallet-connect-core/get-request-params first)]
|
||||
|
||||
{:keys [from] :as tx} (-> event wallet-connect-core/get-request-params first)
|
||||
chain-id (-> event
|
||||
(get-in [:params :chainId])
|
||||
wallet-connect-core/eip155->chain-id)]
|
||||
{:db (update-in db
|
||||
[:wallet-connect/current-request]
|
||||
assoc
|
||||
:address to
|
||||
:raw-data event
|
||||
:address (string/lower-case from)
|
||||
:raw-data tx
|
||||
:chain-id chain-id
|
||||
:display-data display-data)})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
@ -81,12 +87,16 @@
|
|||
(fn [{:keys [db]}]
|
||||
(let [event (wallet-connect-core/get-db-current-request-event db)
|
||||
display-data (.stringify js/JSON (clj->js event) nil 2)
|
||||
{:keys [to]} (-> event wallet-connect-core/get-request-params first)]
|
||||
{:keys [from] :as tx} (-> event wallet-connect-core/get-request-params first)
|
||||
chain-id (-> event
|
||||
(get-in [:params :chainId])
|
||||
wallet-connect-core/eip155->chain-id)]
|
||||
{:db (update-in db
|
||||
[:wallet-connect/current-request]
|
||||
assoc
|
||||
:address to
|
||||
:raw-data event
|
||||
:address (string/lower-case from)
|
||||
:raw-data tx
|
||||
:chain-id chain-id
|
||||
:display-data display-data)})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
@ -103,6 +113,6 @@
|
|||
{:db (update-in db
|
||||
[:wallet-connect/current-request]
|
||||
assoc
|
||||
:address address
|
||||
:raw-data (or parsed-data raw-data)
|
||||
:display-data parsed-data)})))
|
||||
:address (string/lower-case address)
|
||||
:display-data (or parsed-data raw-data)
|
||||
:raw-data raw-data)})))
|
||||
|
|
|
@ -14,17 +14,13 @@
|
|||
[:dispatch [:wallet-connect/respond-personal-sign password]]
|
||||
|
||||
constants/wallet-connect-eth-send-transaction-method
|
||||
[:dispatch
|
||||
[:wallet-connect/respond-build-transaction
|
||||
#(rf/dispatch [:wallet-connect/respond-send-transaction-data password %])]]
|
||||
[:dispatch [:wallet-connect/respond-send-transaction-data password]]
|
||||
|
||||
constants/wallet-connect-eth-sign-method
|
||||
[:dispatch [:wallet-connect/respond-eth-sign password]]
|
||||
|
||||
constants/wallet-connect-eth-sign-transaction-method
|
||||
[:dispatch
|
||||
[:wallet-connect/respond-build-transaction
|
||||
#(rf/dispatch [:wallet-connect/respond-sign-transaction-data password %])]]
|
||||
[:dispatch [:wallet-connect/respond-sign-transaction-data password]]
|
||||
|
||||
constants/wallet-connect-eth-sign-typed-method
|
||||
[:dispatch [:wallet-connect/respond-sign-typed-data password :v1]]
|
||||
|
@ -67,40 +63,27 @@
|
|||
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
|
||||
:on-success #(rf/dispatch [:wallet-connect/send-response %])}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/respond-build-transaction
|
||||
(fn [{:keys [db]} [on-success]]
|
||||
(let [{:keys [raw-data]} (get db :wallet-connect/current-request)
|
||||
chain-id (-> raw-data
|
||||
(get-in [:params :chainId])
|
||||
wallet-connect-core/eip155->chain-id)]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_buildTransaction"
|
||||
:params [chain-id (js/JSON.stringify raw-data)]
|
||||
:on-success on-success
|
||||
:on-error [:wallet-connect/on-sign-error]}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/respond-send-transaction-data
|
||||
(fn [_ [password data]]
|
||||
(let [{:keys [address]
|
||||
message-to-sign :messageToSign} data]
|
||||
{:fx [[:effects.wallet-connect/sign-message
|
||||
(fn [{:keys [db]} [password]]
|
||||
(let [{:keys [chain-id raw-data address]} (get db :wallet-connect/current-request)]
|
||||
{:fx [[:effects.wallet-connect/send-transaction
|
||||
{:password password
|
||||
:address address
|
||||
:data message-to-sign
|
||||
:chain-id chain-id
|
||||
:tx raw-data
|
||||
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
|
||||
:on-success #(rf/dispatch [:wallet-connect/send-response %])}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/respond-sign-transaction-data
|
||||
(fn [_ [password data]]
|
||||
(let [{:keys [address]
|
||||
message-to-sign :messageToSign} data]
|
||||
{:fx [[:effects.wallet-connect/sign-message
|
||||
(fn [{:keys [db]} [password]]
|
||||
(let [{:keys [chain-id raw-data address]} (get db :wallet-connect/current-request)]
|
||||
{:fx [[:effects.wallet-connect/sign-transaction
|
||||
{:password password
|
||||
:address address
|
||||
:data message-to-sign
|
||||
:chain-id chain-id
|
||||
:tx raw-data
|
||||
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
|
||||
:on-success #(rf/dispatch [:wallet-connect/send-response %])}]]})))
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.transactions
|
||||
(:require [cljs-bean.core :as bean]
|
||||
[clojure.string :as string]
|
||||
[oops.core :as oops]
|
||||
[promesa.core :as promesa]
|
||||
[status-im.common.json-rpc.events :as rpc-events]
|
||||
[status-im.constants :as constants]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn- call-rpc
|
||||
"Helper to handle RPC calls to status-go as promises"
|
||||
[method & args]
|
||||
(promesa/create
|
||||
(fn [p-resolve p-reject]
|
||||
(rpc-events/call {:method method
|
||||
:params (vec args)
|
||||
:on-success p-resolve
|
||||
:on-error p-reject
|
||||
:js-response true}))))
|
||||
|
||||
(defn- strip-hex-prefix
|
||||
"Strips the extra 0 in hex value if present"
|
||||
[hex-value]
|
||||
(let [formatted-hex (string/replace hex-value #"^0x0*" "0x")]
|
||||
(if (= formatted-hex "0x")
|
||||
"0x0"
|
||||
formatted-hex)))
|
||||
|
||||
(defn- format-tx-hex-values
|
||||
"Due to how status-go expects hex values, we should remove the extra 0s in transaction hex values e.g. 0x0f -> 0xf"
|
||||
[tx]
|
||||
(let [tx-keys [:gasLimit :gas :gasPrice :nonce :value :maxFeePerGas :maxPriorityFeePerGas]]
|
||||
(reduce (fn [acc tx-key]
|
||||
(if (and (contains? tx tx-key)
|
||||
(not (nil? (get tx tx-key))))
|
||||
(update acc tx-key strip-hex-prefix)
|
||||
acc))
|
||||
tx
|
||||
tx-keys)))
|
||||
|
||||
(defn- prepare-transaction-for-rpc
|
||||
"Formats the transaction and transforms it into a stringified JS object, ready to be passed to an RPC call."
|
||||
[tx]
|
||||
(-> tx
|
||||
format-tx-hex-values
|
||||
bean/->js
|
||||
(transforms/js-stringify 0)))
|
||||
|
||||
(defn wallet-sign-message-rpc
|
||||
[password address data]
|
||||
(-> (call-rpc "wallet_signMessage"
|
||||
data
|
||||
address
|
||||
password)
|
||||
;; NOTE: removing `0x`, as status-go expects the signature without it.
|
||||
(promesa/then #(subs % 2))))
|
||||
|
||||
(defn- wallet-build-transaction-rpc
|
||||
[chain-id tx]
|
||||
(-> (call-rpc "wallet_buildTransaction" chain-id tx)
|
||||
(promesa/then #(hash-map :message-to-sign (oops/oget % "messageToSign")
|
||||
:tx-args (oops/oget % "txArgs")))))
|
||||
|
||||
(defn- wallet-build-raw-transaction-rpc
|
||||
[chain-id tx-args signature]
|
||||
(-> (call-rpc "wallet_buildRawTransaction"
|
||||
chain-id
|
||||
(transforms/js-stringify tx-args 0)
|
||||
signature)
|
||||
(promesa/then #(oops/oget % "rawTx"))))
|
||||
|
||||
(defn- wallet-send-transaction-with-signature-rpc
|
||||
[chain-id tx-args signature]
|
||||
(call-rpc "wallet_sendTransactionWithSignature"
|
||||
chain-id
|
||||
constants/transaction-pending-type-wallet-connect-transfer
|
||||
(transforms/js-stringify tx-args 0)
|
||||
signature))
|
||||
|
||||
(defn sign-transaction
|
||||
[password address tx chain-id]
|
||||
(promesa/let
|
||||
[formatted-tx (prepare-transaction-for-rpc tx)
|
||||
{:keys [message-to-sign tx-args]} (wallet-build-transaction-rpc chain-id formatted-tx)
|
||||
signature (wallet-sign-message-rpc password address message-to-sign)
|
||||
raw-tx (wallet-build-raw-transaction-rpc chain-id tx-args signature)]
|
||||
raw-tx))
|
||||
|
||||
(defn send-transaction
|
||||
[password address tx chain-id]
|
||||
(promesa/let
|
||||
[formatted-tx (prepare-transaction-for-rpc tx)
|
||||
{:keys [message-to-sign tx-args]} (wallet-build-transaction-rpc chain-id formatted-tx)
|
||||
signature (wallet-sign-message-rpc password address message-to-sign)
|
||||
tx (wallet-send-transaction-with-signature-rpc chain-id
|
||||
tx-args
|
||||
signature)]
|
||||
tx))
|
|
@ -39,7 +39,7 @@
|
|||
:<- [:wallet-connect/current-request]
|
||||
:<- [:wallet-connect/pairings]
|
||||
(fn [[request pairings]]
|
||||
(let [dapp-url (get-in request [:raw-data :verifyContext :verified :origin])]
|
||||
(let [dapp-url (get-in request [:event :verifyContext :verified :origin])]
|
||||
(->> pairings
|
||||
(filter (fn [pairing]
|
||||
(= dapp-url (get-in pairing [:peerMetadata :url]))))
|
||||
|
|
Loading…
Reference in New Issue