Wallet Connect message signing (#20693)
* feat: updated signing endpoints and refactor
6e056348...e8aec741
* fix: address review comments
This commit is contained in:
parent
bd9e440839
commit
588692e0eb
|
@ -915,7 +915,7 @@ PODS:
|
|||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
- react-native-compat (2.12.2):
|
||||
- react-native-compat (2.11.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
|
@ -1517,7 +1517,7 @@ SPEC CHECKSUMS:
|
|||
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
|
||||
react-native-blur: 799045500f56146afc46245148080e7b7623cb75
|
||||
react-native-cameraroll: af8eec1e585d053ff485d98ec837f9a8a11b5745
|
||||
react-native-compat: 84e00e8dcff9251278c0d48f2bce81f4502e3925
|
||||
react-native-compat: 3af9add14d349701306d3d052638435f6795ac2c
|
||||
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
|
||||
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
|
||||
react-native-hole-view: 6935448993bac79f2b5a4ad7e9741094cf810679
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
(ns legacy.status-im.utils.hex
|
||||
(:require
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defn normalize-hex
|
||||
[hex]
|
||||
(when hex
|
||||
(string/lower-case (if (string/starts-with? hex "0x")
|
||||
(subs hex 2)
|
||||
hex))))
|
||||
|
||||
(defn valid-hex?
|
||||
[hex]
|
||||
(let [hex (normalize-hex hex)]
|
||||
(and (re-matches #"^[0-9a-fA-F]+$" hex)
|
||||
(not= (js/parseInt hex 16) 0))))
|
|
@ -1,8 +1,8 @@
|
|||
(ns status-im.contexts.wallet.send.utils
|
||||
(:require
|
||||
[legacy.status-im.utils.hex :as utils.hex]
|
||||
[native-module.core :as native-module]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[utils.hex :as utils.hex]
|
||||
[utils.money :as money]))
|
||||
|
||||
(defn amount-in-hex
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.effects
|
||||
(:require
|
||||
[cljs-bean.core :as bean]
|
||||
[native-module.core :as native-module]
|
||||
[promesa.core :as promesa]
|
||||
[re-frame.core :as rf]
|
||||
[react-native.wallet-connect :as wallet-connect]
|
||||
[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.signing :as signing]
|
||||
[status-im.contexts.wallet.wallet-connect.transactions :as transactions]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as transforms]))
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/init
|
||||
|
@ -79,36 +76,48 @@
|
|||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/sign-message
|
||||
(fn [{:keys [password address data on-success on-error]}]
|
||||
(-> {:data data
|
||||
:account address
|
||||
:password (security/safe-unmask-data password)}
|
||||
bean/->js
|
||||
transforms/clj->json
|
||||
native-module/sign-message
|
||||
(promesa/then wallet-connect-core/extract-native-call-signature)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
(fn [{:keys [password address data rpc-method on-success on-error]}]
|
||||
(let [password (security/safe-unmask-data password)]
|
||||
(-> (condp =
|
||||
rpc-method
|
||||
:personal-sign
|
||||
(signing/personal-sign password address data)
|
||||
|
||||
:eth-sign
|
||||
(signing/eth-sign password address data)
|
||||
|
||||
(signing/personal-sign password address data))
|
||||
(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)
|
||||
(-> (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)
|
||||
(-> (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 (security/safe-unmask-data password))
|
||||
(promesa/then wallet-connect-core/extract-native-call-signature)
|
||||
(fn [{:keys [password address data version chain-id on-success on-error]}]
|
||||
(-> (signing/eth-sign-typed-data (security/safe-unmask-data password)
|
||||
address
|
||||
data
|
||||
chain-id
|
||||
version)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
method (wallet-connect-core/get-request-method event)]
|
||||
{:fx [(condp = method
|
||||
constants/wallet-connect-personal-sign-method
|
||||
[:dispatch [:wallet-connect/respond-personal-sign password]]
|
||||
[:dispatch [:wallet-connect/respond-sign-message password :personal-sign]]
|
||||
|
||||
constants/wallet-connect-eth-sign-method
|
||||
[:dispatch [:wallet-connect/respond-sign-message password :eth-sign]]
|
||||
|
||||
constants/wallet-connect-eth-send-transaction-method
|
||||
[: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-sign-transaction-data password]]
|
||||
|
||||
|
@ -30,35 +30,27 @@
|
|||
[:dispatch [:wallet-connect/respond-sign-typed-data password :v4]])]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/respond-eth-sign
|
||||
(fn [{:keys [db]} [password]]
|
||||
(let [{:keys [address raw-data]} (get db :wallet-connect/current-request)]
|
||||
{:fx [[:effects.wallet-connect/sign-message
|
||||
{:password password
|
||||
:address address
|
||||
:data raw-data
|
||||
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
|
||||
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/respond-personal-sign
|
||||
(fn [{:keys [db]} [password]]
|
||||
:wallet-connect/respond-sign-message
|
||||
(fn [{:keys [db]} [password rpc-method]]
|
||||
(let [{:keys [address raw-data]} (get db :wallet-connect/current-request)]
|
||||
{:fx [[:effects.wallet-connect/sign-message
|
||||
{:password password
|
||||
:address address
|
||||
:data raw-data
|
||||
:rpc-method rpc-method
|
||||
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
|
||||
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/respond-sign-typed-data
|
||||
(fn [{:keys [db]} [password typed-data-version]]
|
||||
(let [{:keys [address raw-data]} (get db :wallet-connect/current-request)]
|
||||
(let [{:keys [address raw-data event]} (get db :wallet-connect/current-request)
|
||||
chain-id (get-in event [:params :chainId])]
|
||||
{:fx [[:effects.wallet-connect/sign-typed-data
|
||||
{:password password
|
||||
:address address
|
||||
:data raw-data
|
||||
:chain-id chain-id
|
||||
:version typed-data-version
|
||||
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
|
||||
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.rpc
|
||||
(:require [oops.core :as oops]
|
||||
[promesa.core :as promesa]
|
||||
[status-im.common.json-rpc.events :as rpc-events]
|
||||
[status-im.constants :as constants]
|
||||
[utils.hex :as hex]
|
||||
[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 args
|
||||
:on-success p-resolve
|
||||
:on-error p-reject
|
||||
:js-response true}))))
|
||||
|
||||
(defn wallet-build-transaction
|
||||
[chain-id tx]
|
||||
(promesa/let [res (call-rpc :wallet_buildTransaction chain-id tx)]
|
||||
{:message-to-sign (oops/oget res :messageToSign)
|
||||
:tx-args (oops/oget res :txArgs)}))
|
||||
|
||||
(defn wallet-build-raw-transaction
|
||||
[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
|
||||
[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 wallet-sign-message
|
||||
[message address password]
|
||||
(-> (call-rpc "wallet_signMessage"
|
||||
message
|
||||
address
|
||||
password)
|
||||
(promesa/then hex/normalize-hex)))
|
||||
|
||||
(defn wallet-hash-message-eip-191
|
||||
[message]
|
||||
(call-rpc "wallet_hashMessageEIP191" message))
|
||||
|
||||
(defn wallet-safe-sign-typed-data
|
||||
[data address password chain-id legacy?]
|
||||
(call-rpc "wallet_safeSignTypedDataForDApps"
|
||||
data
|
||||
address
|
||||
password
|
||||
chain-id
|
||||
legacy?))
|
|
@ -0,0 +1,32 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.signing
|
||||
(:require [native-module.core :as native-module]
|
||||
[promesa.core :as promesa]
|
||||
[status-im.contexts.wallet.wallet-connect.core :as core]
|
||||
[status-im.contexts.wallet.wallet-connect.rpc :as rpc]
|
||||
[utils.hex :as hex]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn eth-sign
|
||||
[password address data]
|
||||
(-> {:data data
|
||||
:account address
|
||||
:password password}
|
||||
transforms/clj->json
|
||||
native-module/sign-message
|
||||
(promesa/then core/extract-native-call-signature)))
|
||||
|
||||
(defn personal-sign
|
||||
[password address data]
|
||||
(-> (rpc/wallet-hash-message-eip-191 data)
|
||||
(promesa/then #(rpc/wallet-sign-message % address password))
|
||||
(promesa/then hex/prefix-hex)))
|
||||
|
||||
(defn eth-sign-typed-data
|
||||
[password address data chain-id-eip155 version]
|
||||
(let [legacy? (= version :v1)
|
||||
chain-id (core/eip155->chain-id chain-id-eip155)]
|
||||
(rpc/wallet-safe-sign-typed-data data
|
||||
address
|
||||
password
|
||||
chain-id
|
||||
legacy?)))
|
|
@ -1,23 +1,10 @@
|
|||
(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]
|
||||
[status-im.contexts.wallet.wallet-connect.rpc :as rpc]
|
||||
[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]
|
||||
|
@ -46,53 +33,22 @@
|
|||
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)]
|
||||
{:keys [message-to-sign tx-args]} (rpc/wallet-build-transaction chain-id formatted-tx)
|
||||
signature (rpc/wallet-sign-message message-to-sign address password)
|
||||
raw-tx (rpc/wallet-build-raw-transaction 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
|
||||
{:keys [message-to-sign tx-args]} (rpc/wallet-build-transaction chain-id formatted-tx)
|
||||
signature (rpc/wallet-sign-message message-to-sign address password)
|
||||
tx (rpc/wallet-send-transaction-with-signature chain-id
|
||||
tx-args
|
||||
signature)]
|
||||
tx))
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
(ns status-im.subs.wallet.activities
|
||||
(:require
|
||||
[legacy.status-im.utils.hex :as utils.hex]
|
||||
[native-module.core :as native-module]
|
||||
[quo.foundations.resources :as quo.resources]
|
||||
[quo.foundations.resources]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.contexts.wallet.common.activity-tab.constants :as constants]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.hex :as utils.hex]
|
||||
[utils.money :as money]))
|
||||
|
||||
(def precision 6)
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
:<- [:wallet-connect/current-request]
|
||||
(fn [request]
|
||||
(-> request
|
||||
(get-in [:raw-data :params :chainId])
|
||||
(get-in [:event :params :chainId])
|
||||
(wallet-connect-core/eip155->chain-id)
|
||||
(networks/get-network-details))))
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
(ns utils.hex
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn normalize-hex
|
||||
[hex]
|
||||
(when hex
|
||||
(string/lower-case (if (string/starts-with? hex "0x")
|
||||
(subs hex 2)
|
||||
hex))))
|
||||
|
||||
(schema/=> normalize-hex
|
||||
[:=>
|
||||
[:cat [:maybe :string]]
|
||||
[:maybe :string]])
|
||||
|
||||
(defn prefix-hex
|
||||
[hex]
|
||||
(if (string/starts-with? hex "0x")
|
||||
hex
|
||||
(str "0x" hex)))
|
||||
|
||||
(schema/=> prefix-hex
|
||||
[:=>
|
||||
[:cat :string]
|
||||
:string])
|
Loading…
Reference in New Issue