Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9983dd5f7d | ||
|
|
1a22a0ac10 | ||
|
|
616b5224c7 | ||
|
|
0d8ac7de81 | ||
|
|
e9f97f7b3b |
@@ -4,7 +4,8 @@
|
||||
["@walletconnect/utils" :as wc-utils]
|
||||
["@walletconnect/web3wallet$default" :as Web3Wallet]
|
||||
[cljs-bean.core :as bean]
|
||||
[oops.core :as oops]))
|
||||
[oops.core :as oops]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn- wallet-connect-core
|
||||
[project-id]
|
||||
@@ -34,7 +35,7 @@
|
||||
(defn parse-uri
|
||||
[uri]
|
||||
(-> (oops/ocall wc-utils "parseUri" uri)
|
||||
(bean/->clj)))
|
||||
transforms/js->clj))
|
||||
|
||||
(defn respond-session-request
|
||||
[{:keys [web3-wallet topic id result error]}]
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
[status-im.common.validation.general :as validators]
|
||||
[status-im.contexts.communities.events]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.uri :as wc-uri]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.address :as utils-address]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.ethereum.eip.eip681 :as eip681]
|
||||
@@ -99,9 +98,7 @@
|
||||
;; TODO: https://github.com/status-im/status-mobile/issues/18744
|
||||
nil
|
||||
|
||||
(and
|
||||
(wc-uri/valid-uri? scanned-text)
|
||||
(ff/enabled? ::ff/wallet.wallet-connect))
|
||||
(-> scanned-text wc-uri/parse wc-uri/valid?)
|
||||
(handle-wallet-connect scanned-text)
|
||||
|
||||
(url? scanned-text)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
(ns status-im.contexts.wallet.common.utils.account
|
||||
(:require [clojure.string :as string]))
|
||||
|
||||
(defn filter-operable
|
||||
[accounts]
|
||||
(filter #(and (:operable? %)
|
||||
(not (:watch-only? %)))
|
||||
accounts))
|
||||
|
||||
(defn to-eip155
|
||||
[address chain-id]
|
||||
(str chain-id ":" address))
|
||||
|
||||
(defn from-eip155
|
||||
[address]
|
||||
(-> address
|
||||
(string/split #":")
|
||||
last))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.wallet.connected-dapps.disconnect-dapp.view :as disconnect-dapp]
|
||||
[status-im.contexts.wallet.connected-dapps.style :as style]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.dapp :as dapp]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.string]))
|
||||
@@ -107,17 +107,15 @@
|
||||
:content-container-style (style/dapps-list theme)
|
||||
:render-fn (fn [{:keys [topic pairingTopic name url iconUrl]}]
|
||||
[quo/dapp
|
||||
{:dapp {:avatar
|
||||
(data-store/compute-dapp-icon-path
|
||||
iconUrl
|
||||
url)
|
||||
:name
|
||||
(data-store/compute-dapp-name
|
||||
name
|
||||
url)
|
||||
:value url
|
||||
:topic topic
|
||||
:pairing-topic pairingTopic
|
||||
{:dapp {:avatar (dapp/compute-icon
|
||||
iconUrl
|
||||
url)
|
||||
:name (dapp/compute-name
|
||||
name
|
||||
url)
|
||||
:value url
|
||||
:topic topic
|
||||
:pairing-topic pairingTopic
|
||||
:customization-color customization-color}
|
||||
:accessibility-label (str "dapp-" topic)
|
||||
:state :default
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[react-native.wallet-connect :as wallet-connect]
|
||||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.sessions :as sessions]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.session :as session]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.signing :as signing]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.transactions :as transactions]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.typed-data :as typed-data]
|
||||
@@ -44,14 +44,14 @@
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/disconnect
|
||||
(fn [{:keys [web3-wallet topic on-success on-fail]}]
|
||||
(-> (sessions/disconnect web3-wallet topic)
|
||||
(-> (session/disconnect web3-wallet topic)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-fail))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/approve-session
|
||||
(fn [{:keys [web3-wallet proposal-request session-networks address on-success on-fail]}]
|
||||
(-> (sessions/approve
|
||||
(-> (session/approve
|
||||
{:web3-wallet web3-wallet
|
||||
:proposal-request proposal-request
|
||||
:address address
|
||||
@@ -145,6 +145,6 @@
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/get-sessions
|
||||
(fn [{:keys [web3-wallet addresses online? on-success on-error]}]
|
||||
(-> (sessions/get-sessions web3-wallet addresses online?)
|
||||
(-> (session/get-sessions web3-wallet addresses online?)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.events.session-proposals
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as rf]
|
||||
[react-native.wallet-connect :as wallet-connect]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.common.utils.account :as account-utils]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.sessions :as sessions]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.proposal :as session-proposal]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.session :as sessions]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.uri :as uri]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]))
|
||||
@@ -23,37 +24,27 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-scan-connection
|
||||
(fn [{:keys [db]} [scanned-text]]
|
||||
(let [network-status (:network/status db)
|
||||
parsed-uri (wallet-connect/parse-uri scanned-text)
|
||||
version (:version parsed-uri)
|
||||
valid-wc-uri? (uri/valid-wc-uri? parsed-uri)
|
||||
expired? (-> parsed-uri
|
||||
:expiryTimestamp
|
||||
uri/timestamp-expired?)
|
||||
version-supported? (uri/version-supported? version)]
|
||||
(if (or (not valid-wc-uri?)
|
||||
(not version-supported?)
|
||||
(= network-status :offline)
|
||||
expired?)
|
||||
(let [network-status (:network/status db)
|
||||
parsed-uri (uri/parse scanned-text)
|
||||
error-toast (cond
|
||||
(= network-status :offline)
|
||||
(i18n/label :t/wallet-connect-no-internet-warning)
|
||||
|
||||
(not (uri/valid? parsed-uri))
|
||||
(i18n/label :t/wallet-connect-wrong-qr)
|
||||
|
||||
(uri/expired? parsed-uri)
|
||||
(i18n/label :t/wallet-connect-qr-expired)
|
||||
|
||||
(not (uri/version-supported? parsed-uri))
|
||||
(i18n/label :t/wallet-connect-version-not-supported
|
||||
{:version (:version parsed-uri)}))]
|
||||
(if error-toast
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text (cond (= network-status :offline)
|
||||
(i18n/label :t/wallet-connect-no-internet-warning)
|
||||
|
||||
(not valid-wc-uri?)
|
||||
(i18n/label :t/wallet-connect-wrong-qr)
|
||||
|
||||
expired?
|
||||
(i18n/label :t/wallet-connect-qr-expired)
|
||||
|
||||
(not version-supported?)
|
||||
(i18n/label :t/wallet-connect-version-not-supported
|
||||
{:version version})
|
||||
|
||||
:else
|
||||
(i18n/label :t/something-went-wrong))}]]]}
|
||||
:text error-toast}]]]}
|
||||
{:fx [[:dispatch [:wallet-connect/pair scanned-text]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
@@ -63,11 +54,12 @@
|
||||
(let [accounts (get-in db [:wallet :accounts])
|
||||
current-viewing-address (get-in db [:wallet :current-viewing-account-address])
|
||||
sessions (get db :wallet-connect/sessions)
|
||||
available-accounts (sessions/filter-operable-accounts (vals accounts))
|
||||
available-accounts (-> accounts vals account-utils/filter-operable)
|
||||
latest-connected-account-address (sessions/latest-connected-account-address sessions)
|
||||
networks (networks/get-networks-by-mode db)
|
||||
session-networks (networks/proposal-networks-intersection proposal networks)
|
||||
required-networks-supported? (networks/required-networks-supported? proposal networks)]
|
||||
session-networks (session-proposal/networks-intersection proposal networks)
|
||||
required-networks-supported? (session-proposal/required-networks-supported? proposal
|
||||
networks)]
|
||||
(if (and (not-empty session-networks) required-networks-supported?)
|
||||
{:db (update db
|
||||
:wallet-connect/current-proposal assoc
|
||||
@@ -91,13 +83,12 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/show-session-networks-unsupported-toast
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(let [{:keys [name url]} (data-store/get-session-dapp-metadata proposal)]
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme (:theme db)
|
||||
:text (i18n/label :t/wallet-connect-networks-not-supported
|
||||
{:dapp (data-store/compute-dapp-name name url)})}]]]})))
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme (:theme db)
|
||||
:text (i18n/label :t/wallet-connect-networks-not-supported
|
||||
{:dapp (session-proposal/dapp-name proposal)})}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/reset-current-session-proposal
|
||||
@@ -118,13 +109,10 @@
|
||||
(map networks/chain-id->eip155)
|
||||
vec)
|
||||
current-address (get-in db [:wallet-connect/current-proposal :address])
|
||||
network-status (:network/status db)
|
||||
expired? (-> current-proposal
|
||||
(get-in [:params :expiryTimestamp])
|
||||
uri/timestamp-expired?)]
|
||||
network-status (:network/status db)]
|
||||
(if (= network-status :online)
|
||||
{:db (assoc-in db [:wallet-connect/current-proposal :response-sent?] true)
|
||||
:fx [(if expired?
|
||||
:fx [(if (session-proposal/expired? current-proposal)
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:id :wallet-connect-proposal-expired
|
||||
@@ -173,11 +161,9 @@
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)
|
||||
{:keys [request response-sent?]} (:wallet-connect/current-proposal db)
|
||||
networks (networks/get-proposal-networks (or proposal request))
|
||||
rejected? (nil? proposal)
|
||||
dapp-name (-> (data-store/get-session-dapp-metadata (or proposal
|
||||
request))
|
||||
:name)]
|
||||
networks (session-proposal/networks (or proposal request))
|
||||
dapp-name (session-proposal/dapp-name (or proposal request))
|
||||
rejected? (nil? proposal)]
|
||||
{:fx (concat
|
||||
(when-not response-sent?
|
||||
[[:effects.wallet-connect/reject-session-proposal
|
||||
|
||||
@@ -6,29 +6,32 @@
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.request :as session-request]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.transactions :as transactions]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.typed-data :as typed-data]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
[utils.transforms :as transforms]
|
||||
[cljs.pprint :as pprint]))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/show-request-modal
|
||||
(fn [{:keys [db]}]
|
||||
(let [event (get-in db [:wallet-connect/current-request :event])
|
||||
method (data-store/get-request-method event)
|
||||
screen (data-store/method-to-screen method)]
|
||||
(let [screen (-> db
|
||||
data-store/get-db-current-request-event
|
||||
session-request/screen)]
|
||||
(if screen
|
||||
{:fx [[:dispatch [:open-modal screen]]]}
|
||||
(log/error "Didn't find screen for Wallet Connect method"
|
||||
{:method method
|
||||
:event :wallet-connect/process-session-request})))))
|
||||
{:event :wallet-connect/process-session-request})))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/process-session-request
|
||||
(fn [{:keys [db]} [event]]
|
||||
(let [method (data-store/get-request-method event)
|
||||
existing-event (get-in db [:wallet-connect/current-request :event])]
|
||||
(pprint/pprint event)
|
||||
(let [method (session-request/method event)
|
||||
existing-event (data-store/get-db-current-request-event db)]
|
||||
(log/info "Processing Wallet Connect session request" method)
|
||||
;; NOTE: make sure we don't show two requests at the same time
|
||||
(when-not existing-event
|
||||
@@ -95,17 +98,14 @@
|
||||
:address address
|
||||
:raw-data prepared-tx
|
||||
:transaction tx
|
||||
:chain-id chain-id
|
||||
:display-data display-data)})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/process-eth-send-transaction
|
||||
(fn [{:keys [db]} [{:keys [on-success]}]]
|
||||
(let [event (data-store/get-db-current-request-event db)
|
||||
tx (-> event data-store/get-request-params first)
|
||||
chain-id (-> event
|
||||
(get-in [:params :chainId])
|
||||
networks/eip155->chain-id)]
|
||||
tx (-> event session-request/params first)
|
||||
chain-id (session-request/chain event)]
|
||||
(when tx
|
||||
{:fx [[:effects.wallet-connect/prepare-transaction
|
||||
{:tx tx
|
||||
@@ -120,10 +120,8 @@
|
||||
:wallet-connect/process-eth-sign-transaction
|
||||
(fn [{:keys [db]}]
|
||||
(let [event (data-store/get-db-current-request-event db)
|
||||
tx (-> event data-store/get-request-params first)
|
||||
chain-id (-> event
|
||||
(get-in [:params :chainId])
|
||||
networks/eip155->chain-id)]
|
||||
tx (-> event session-request/params first)
|
||||
chain-id (session-request/chain event)]
|
||||
{:fx [[:effects.wallet-connect/prepare-transaction
|
||||
{:tx tx
|
||||
:chain-id chain-id
|
||||
@@ -135,9 +133,9 @@
|
||||
(fn [{:keys [db]}]
|
||||
(try
|
||||
(let [[address raw-data] (data-store/get-db-current-request-params db)
|
||||
session-chain-id (-> (data-store/get-db-current-request-event db)
|
||||
(get-in [:params :chainId])
|
||||
networks/eip155->chain-id)
|
||||
session-chain-id (-> db
|
||||
data-store/get-db-current-request-event
|
||||
session-request/chain)
|
||||
typed-data (-> raw-data
|
||||
transforms/js-parse
|
||||
transforms/js->clj)
|
||||
@@ -189,11 +187,10 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-processing-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(let [{:keys [address event]} (get db :wallet-connect/current-request)
|
||||
method (data-store/get-request-method event)]
|
||||
(let [event (data-store/get-db-current-request-event db)
|
||||
method (session-request/method event)]
|
||||
(log/error "Failed to process Wallet Connect request"
|
||||
{:error error
|
||||
:address address
|
||||
:method method
|
||||
:wallet-connect-event event
|
||||
:event :wallet-connect/on-processing-error})
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
(:require [re-frame.core :as rf]
|
||||
[react-native.wallet-connect :as wallet-connect]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.uri :as uri]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.request :as session-request]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.transforms :as transforms]))
|
||||
@@ -12,18 +11,15 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/respond-current-session
|
||||
(fn [{:keys [db]} [password]]
|
||||
(let [event (get-in db [:wallet-connect/current-request :event])
|
||||
method (data-store/get-request-method event)
|
||||
screen (data-store/method-to-screen method)
|
||||
expiry (get-in event [:params :request :expiryTimestamp])]
|
||||
(if (uri/timestamp-expired? expiry)
|
||||
(let [event (data-store/get-db-current-request-event db)]
|
||||
(if (session-request/expired? event)
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:id :new-wallet-account-created
|
||||
:type :negative
|
||||
:text (i18n/label :t/wallet-connect-request-expired)}]]
|
||||
[:dispatch [:dismiss-modal screen]]]}
|
||||
{:fx [(condp = method
|
||||
[:dispatch [:dismiss-modal (session-request/screen event)]]]}
|
||||
{:fx [(condp = (session-request/method event)
|
||||
constants/wallet-connect-personal-sign-method
|
||||
[:dispatch [:wallet-connect/respond-sign-message password :personal-sign]]
|
||||
|
||||
@@ -58,7 +54,7 @@
|
||||
:wallet-connect/respond-sign-typed-data
|
||||
(fn [{:keys [db]} [password typed-data-version]]
|
||||
(let [{:keys [address raw-data event]} (get db :wallet-connect/current-request)
|
||||
chain-id (get-in event [:params :chainId])]
|
||||
chain-id (session-request/chain event)]
|
||||
{:fx [[:effects.wallet-connect/sign-typed-data
|
||||
{:password password
|
||||
:address address
|
||||
@@ -71,8 +67,9 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/respond-send-transaction-data
|
||||
(fn [{:keys [db]} [password]]
|
||||
(let [{:keys [chain-id raw-data address]} (get db :wallet-connect/current-request)
|
||||
{:keys [tx-hash tx-args]} raw-data]
|
||||
(let [{:keys [raw-data address event]} (get db :wallet-connect/current-request)
|
||||
{:keys [tx-hash tx-args]} raw-data
|
||||
chain-id (session-request/chain event)]
|
||||
{:fx [[:effects.wallet-connect/send-transaction
|
||||
{:password password
|
||||
:address address
|
||||
@@ -100,7 +97,7 @@
|
||||
:wallet-connect/on-sign-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(let [{:keys [raw-data address event]} (get db :wallet-connect/current-request)
|
||||
method (data-store/get-request-method event)]
|
||||
method (session-request/method event)]
|
||||
(log/error "Failed to sign Wallet Connect request"
|
||||
{:error error
|
||||
:address address
|
||||
@@ -118,8 +115,8 @@
|
||||
:wallet-connect/send-response
|
||||
(fn [{:keys [db]} [{:keys [request result error]}]]
|
||||
(when-let [{:keys [id topic] :as event} (or request
|
||||
(get-in db [:wallet-connect/current-request :event]))]
|
||||
(let [method (data-store/get-request-method event)
|
||||
(data-store/get-db-current-request-event db))]
|
||||
(let [method (session-request/method event)
|
||||
web3-wallet (get db :wallet-connect/web3-wallet)]
|
||||
{:db (assoc-in db [:wallet-connect/current-request :response-sent?] true)
|
||||
:fx [[:effects.wallet-connect/respond-session-request
|
||||
@@ -141,13 +138,14 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/redirect-to-dapp
|
||||
(fn [{:keys [db]} [url]]
|
||||
(let [redirect-url (or url
|
||||
(->> (get db :wallet-connect/current-request)
|
||||
(data-store/get-current-request-dapp
|
||||
(get db :wallet-connect/sessions))
|
||||
:sessionJson
|
||||
transforms/json->clj
|
||||
data-store/get-dapp-redirect-url))]
|
||||
(let [sessions (get db :wallet-connect/sessions)
|
||||
redirect-url (or url
|
||||
(-> db
|
||||
data-store/get-db-current-request-event
|
||||
(data-store/get-current-request-dapp sessions)
|
||||
:sessionJson
|
||||
transforms/json->clj
|
||||
data-store/get-dapp-redirect-url))]
|
||||
{:fx [[:effects/open-url redirect-url]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
@@ -155,15 +153,14 @@
|
||||
(fn [{:keys [db]} _]
|
||||
(let [screen (-> db
|
||||
(get-in [:wallet-connect/current-request :event])
|
||||
data-store/get-request-method
|
||||
data-store/method-to-screen)]
|
||||
session-request/screen)]
|
||||
{:fx [[:dispatch [:dismiss-modal screen]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/finish-session-request
|
||||
(fn [{:keys [db]} [result]]
|
||||
(let [event (get-in db [:wallet-connect/current-request :event])
|
||||
method (data-store/get-request-method event)
|
||||
method (session-request/method event)
|
||||
toast-text (condp contains? method
|
||||
constants/wallet-connect-message-signing-methods
|
||||
(i18n/label :t/wallet-connect-message-request-success-toast)
|
||||
@@ -192,11 +189,11 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-request-modal-dismissed
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [response-sent? event] :as request} (get db :wallet-connect/current-request)
|
||||
method (data-store/get-request-method event)
|
||||
dapp (->> (get db :wallet-connect/sessions)
|
||||
(data-store/get-current-request-dapp request)
|
||||
:name)]
|
||||
(let [{:keys [response-sent? event]} (get db :wallet-connect/current-request)
|
||||
method (session-request/method event)
|
||||
dapp (->> (get db :wallet-connect/sessions)
|
||||
(data-store/get-current-request-dapp event)
|
||||
:name)]
|
||||
{:fx (concat
|
||||
(when-not response-sent?
|
||||
[[:dispatch
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.sessions :as sessions]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.session :as session-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]))
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.contexts.wallet.common.utils.account :as account-utils]))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-delete
|
||||
@@ -58,7 +59,7 @@
|
||||
(fn [{:keys [db]}]
|
||||
(let [addresses (->> (get-in db [:wallet :accounts])
|
||||
vals
|
||||
sessions/filter-operable-accounts
|
||||
account-utils/filter-operable
|
||||
(map :address))]
|
||||
(if (not (seq addresses))
|
||||
;; NOTE: Re-trying to get active sessions if accounts weren't loaded yet during
|
||||
@@ -94,7 +95,7 @@
|
||||
:wallet-connect/sessions
|
||||
(fn [sessions]
|
||||
(->> new-session
|
||||
sessions/sdk-session->db-session
|
||||
session-utils/session->db
|
||||
(conj sessions))))}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.wallet.wallet-connect.modals.common.header.style :as style]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]))
|
||||
[status-im.contexts.wallet.wallet-connect.utils.dapp :as dapp-utils]))
|
||||
|
||||
(defn view
|
||||
[{:keys [label dapp account]}]
|
||||
[rn/view {:style style/header-container}
|
||||
(let [{:keys [name iconUrl url]} dapp
|
||||
image-source (data-store/compute-dapp-icon-path iconUrl url)]
|
||||
image-source (dapp-utils/compute-icon iconUrl url)]
|
||||
[rn/view {:style style/dapp-container}
|
||||
[quo/summary-tag
|
||||
{:type :dapp
|
||||
|
||||
@@ -7,22 +7,19 @@
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.contexts.wallet.wallet-connect.modals.session-proposal.style :as style]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as data-store]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.string]))
|
||||
|
||||
(defn- dapp-metadata
|
||||
[]
|
||||
(let [proposer (rf/sub [:wallet-connect/session-proposer])
|
||||
{:keys [icons name url]} (:metadata proposer)
|
||||
first-icon (first icons)
|
||||
dapp-name (data-store/compute-dapp-name name url)
|
||||
profile-picture (data-store/compute-dapp-icon-path first-icon url)]
|
||||
(let [dapp-name (rf/sub [:wallet-connect/session-proposer-name])
|
||||
dapp-icon (rf/sub [:wallet-connect/session-proposer-icon])
|
||||
dapp-url (rf/sub [:wallet-connect/session-proposer-url])]
|
||||
[:<>
|
||||
[rn/view {:style style/dapp-avatar}
|
||||
[quo/user-avatar
|
||||
{:profile-picture profile-picture
|
||||
{:profile-picture dapp-icon
|
||||
:size :big
|
||||
:full-name dapp-name}]]
|
||||
[quo/page-top
|
||||
@@ -31,7 +28,7 @@
|
||||
:context-tag {:type :icon
|
||||
:size 32
|
||||
:icon :i/link
|
||||
:context url}}]]))
|
||||
:context dapp-url}}]]))
|
||||
|
||||
(defn- approval-note
|
||||
[]
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.utils.dapp
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
utils.string))
|
||||
|
||||
(defn compute-name
|
||||
"Sometimes dapps have no name or an empty name. Return url as name in that case"
|
||||
[name url]
|
||||
(if (seq name)
|
||||
name
|
||||
(when (seq url)
|
||||
(-> url
|
||||
utils.string/remove-trailing-slash
|
||||
utils.string/remove-http-prefix
|
||||
string/capitalize))))
|
||||
|
||||
(defn compute-icon
|
||||
"Some dapps have icons with relative paths, make paths absolute in those cases, send nil if icon is missing"
|
||||
[icon-path url]
|
||||
(when (and (seq icon-path)
|
||||
(seq url))
|
||||
(if (string/starts-with? icon-path "http")
|
||||
icon-path
|
||||
(str (utils.string/remove-trailing-slash url) icon-path))))
|
||||
|
||||
(defn best-icon
|
||||
"Find the icon format from the provided list that can be rendered (prefer images)"
|
||||
[icons]
|
||||
(let [image-extensions [".png" ".jpg" ".jpeg"]
|
||||
image? (fn [icon]
|
||||
(some #(string/ends-with? icon %) image-extensions))]
|
||||
(or (first (filter image? icons))
|
||||
(first icons))))
|
||||
@@ -1,65 +1,22 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.utils.data-store
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as wallet-utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.request :as session-request]
|
||||
utils.string
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn compute-dapp-name
|
||||
"Sometimes dapps have no name or an empty name. Return url as name in that case"
|
||||
[name url]
|
||||
(if (seq name)
|
||||
name
|
||||
(when (seq url)
|
||||
(-> url
|
||||
utils.string/remove-trailing-slash
|
||||
utils.string/remove-http-prefix
|
||||
string/capitalize))))
|
||||
|
||||
(defn compute-dapp-icon-path
|
||||
"Some dapps have icons with relative paths, make paths absolute in those cases, send nil if icon is missing"
|
||||
[icon-path url]
|
||||
(when (and (seq icon-path)
|
||||
(seq url))
|
||||
(if (string/starts-with? icon-path "http")
|
||||
icon-path
|
||||
(str (utils.string/remove-trailing-slash url) icon-path))))
|
||||
|
||||
(def method-to-screen
|
||||
{constants/wallet-connect-personal-sign-method :screen/wallet-connect.sign-message
|
||||
constants/wallet-connect-eth-sign-typed-method :screen/wallet-connect.sign-message
|
||||
constants/wallet-connect-eth-sign-method :screen/wallet-connect.sign-message
|
||||
constants/wallet-connect-eth-sign-typed-v4-method :screen/wallet-connect.sign-message
|
||||
constants/wallet-connect-eth-send-transaction-method :screen/wallet-connect.send-transaction
|
||||
constants/wallet-connect-eth-sign-transaction-method :screen/wallet-connect.sign-transaction})
|
||||
|
||||
(defn extract-native-call-signature
|
||||
[data]
|
||||
(-> data transforms/json->clj :result))
|
||||
|
||||
(defn get-request-method
|
||||
[event]
|
||||
(get-in event [:params :request :method]))
|
||||
|
||||
(defn get-request-params
|
||||
[event]
|
||||
(get-in event [:params :request :params]))
|
||||
|
||||
(defn get-db-current-request-event
|
||||
[db]
|
||||
(get-in db [:wallet-connect/current-request :event]))
|
||||
|
||||
(defn get-session-dapp-metadata
|
||||
[proposal]
|
||||
(let [metadata (get-in proposal [:params :proposer :metadata])
|
||||
origin (get-in proposal [:verifyContext :verified :origin])]
|
||||
(or metadata {:url origin})))
|
||||
|
||||
(defn get-current-request-dapp
|
||||
[request sessions]
|
||||
(let [dapp-url (get-in request [:event :verifyContext :verified :origin])]
|
||||
[event sessions]
|
||||
(let [dapp-url (session-request/url event)]
|
||||
(->> sessions
|
||||
(filter (fn [session]
|
||||
(= (utils.string/remove-trailing-slash dapp-url)
|
||||
@@ -78,7 +35,7 @@
|
||||
[db]
|
||||
(-> db
|
||||
get-db-current-request-event
|
||||
get-request-params))
|
||||
session-request/params))
|
||||
|
||||
(defn get-total-connected-dapps
|
||||
[db]
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
|
||||
(deftest get-current-request-dapp-test
|
||||
(testing "returns the correct dapp based on the request's origin"
|
||||
(let [request {:event {:verifyContext {:verified {:origin "https://dapp.com"}}}}
|
||||
(let [request {:verifyContext {:verified {:origin "https://dapp.com"}}}
|
||||
sessions [{:url "https://dapp.com"}
|
||||
{:url "https://anotherdapp.com"}]]
|
||||
(is (= {:url "https://dapp.com"}
|
||||
(sut/get-current-request-dapp request sessions)))))
|
||||
|
||||
(testing "returns nil if no matching dapp is found"
|
||||
(let [request {:event {:verifyContext {:verified {:origin "https://dapp.com"}}}}
|
||||
(let [request {:verifyContext {:verified {:origin "https://dapp.com"}}}
|
||||
sessions [{:url "https://anotherdapp.com"}]]
|
||||
(is (nil? (sut/get-current-request-dapp request sessions))))))
|
||||
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
last
|
||||
edn/read-string))
|
||||
|
||||
(defn format-eip155-address
|
||||
[address chain-id]
|
||||
(str chain-id ":" address))
|
||||
|
||||
(defn- add-full-testnet-name
|
||||
"Updates the `:full-name` key with the full testnet name if using testnet `:chain-id`.\n
|
||||
e.g. `{:full-name \"Mainnet\"}` -> `{:full-name \"Mainnet Sepolia\"`}`"
|
||||
@@ -49,33 +45,19 @@
|
||||
(set/subset? chain-ids constants/sepolia-chain-ids)
|
||||
(set/subset? chain-ids constants/mainnet-chain-ids))))
|
||||
|
||||
(defn get-proposal-networks
|
||||
[proposal]
|
||||
(let [required-namespaces (get-in proposal [:params :requiredNamespaces])
|
||||
optional-namespaces (get-in proposal [:params :optionalNamespaces])]
|
||||
(->> [required-namespaces optional-namespaces]
|
||||
(map #(get-in % [:eip155 :chains]))
|
||||
(apply concat)
|
||||
(into #{}))))
|
||||
|
||||
(defn proposal-networks-intersection
|
||||
[proposal supported-networks]
|
||||
(let [proposed-networks (get-proposal-networks proposal)]
|
||||
(->> supported-networks
|
||||
(filter #(->> %
|
||||
chain-id->eip155
|
||||
(contains? proposed-networks))))))
|
||||
(defn networks-intersection
|
||||
[proposed-networks supported-networks]
|
||||
(->> supported-networks
|
||||
(filter #(->> %
|
||||
chain-id->eip155
|
||||
(contains? proposed-networks)))))
|
||||
|
||||
(defn required-networks-supported?
|
||||
[proposal supported-networks]
|
||||
(let [supported-namespaces #{:eip155}
|
||||
required-namespaces (get-in proposal [:params :requiredNamespaces])]
|
||||
(when (every? #(contains? supported-namespaces %)
|
||||
(keys required-namespaces))
|
||||
(let [required-networks (get-in required-namespaces [:eip155 :chains])
|
||||
supported-eip155 (set (map chain-id->eip155 supported-networks))]
|
||||
(every? #(contains? supported-eip155 %)
|
||||
required-networks)))))
|
||||
[required-networks supported-networks]
|
||||
(every? #(-> (map chain-id->eip155 supported-networks)
|
||||
set
|
||||
(contains? %))
|
||||
required-networks))
|
||||
|
||||
(defn get-networks-by-mode
|
||||
[db]
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.utils.proposal
|
||||
(:require [clojure.string :as string]
|
||||
[schema.core :as schema]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.dapp :as dapp-utils]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks-utils]
|
||||
[utils.datetime :as datetime]))
|
||||
|
||||
(def ^:private ?proposer-metadata
|
||||
[:map
|
||||
[:name {:optional true} :string]
|
||||
[:url {:optional true} :string]
|
||||
[:description {:optional true} :string]
|
||||
[:icons {:optional true} [:sequential :string]]])
|
||||
|
||||
(def ^:private ?namespace
|
||||
[:map
|
||||
[:methods [:sequential :string]]
|
||||
[:chains [:sequential :string]]
|
||||
[:events [:sequential :string]]])
|
||||
|
||||
(def ^:private ?proposal
|
||||
[:map
|
||||
[:id :int]
|
||||
[:verifyContext
|
||||
[:map
|
||||
[:verified
|
||||
[:map
|
||||
[:validation :string]
|
||||
[:origin :string]
|
||||
[:verifyUrl :string]
|
||||
[:isScam {:optional true} :boolean]]]]]
|
||||
[:params
|
||||
[:map
|
||||
[:id :int]
|
||||
[:expiryTimestamp :int]
|
||||
[:pairingTopic :string]
|
||||
[:requiredNamespaces [:map-of :keyword ?namespace]]
|
||||
[:optionalNamespaces [:map-of :keyword ?namespace]]
|
||||
[:relays [:sequential :any]]
|
||||
[:proposer
|
||||
[:map
|
||||
[:publicKey :string]
|
||||
[:metadata ?proposer-metadata]]]]]])
|
||||
|
||||
(defn expired?
|
||||
[proposal]
|
||||
(some-> proposal
|
||||
:params
|
||||
:expiryTimestamp
|
||||
datetime/timestamp-expired?))
|
||||
|
||||
(schema/=> expired?
|
||||
[:=>
|
||||
[:cat ?proposal]
|
||||
:boolean])
|
||||
|
||||
(defn dapp-metadata
|
||||
[proposal]
|
||||
(let [metadata (get-in proposal [:params :proposer :metadata])
|
||||
origin (get-in proposal [:verifyContext :verified :origin])]
|
||||
(or metadata {:url origin})))
|
||||
|
||||
(schema/=> dapp-metadata
|
||||
[:=>
|
||||
[:cat ?proposal]
|
||||
?proposer-metadata])
|
||||
|
||||
(defn dapp-name
|
||||
[proposal]
|
||||
(let [{:keys [name url]} (-> proposal dapp-metadata)]
|
||||
(dapp-utils/compute-name name url)))
|
||||
|
||||
(schema/=> dapp-name
|
||||
[:=>
|
||||
[:cat ?proposal]
|
||||
[:maybe :string]])
|
||||
|
||||
(defn dapp-icon
|
||||
[proposal]
|
||||
(let [{:keys [icons url]} (-> proposal dapp-metadata)
|
||||
icon (dapp-utils/best-icon icons)]
|
||||
(dapp-utils/compute-icon icon url)))
|
||||
|
||||
(schema/=> dapp-icon
|
||||
[:=>
|
||||
[:cat ?proposal]
|
||||
[:maybe :string]])
|
||||
|
||||
(defn dapp-url
|
||||
[proposal]
|
||||
(-> proposal dapp-metadata :url))
|
||||
|
||||
(schema/=> dapp-url
|
||||
[:=>
|
||||
[:cat ?proposal]
|
||||
[:maybe :string]])
|
||||
|
||||
(defn networks
|
||||
[proposal]
|
||||
(let [required-namespaces (get-in proposal [:params :requiredNamespaces])
|
||||
optional-namespaces (get-in proposal [:params :optionalNamespaces])]
|
||||
(->> [required-namespaces optional-namespaces]
|
||||
(map #(get-in % [:eip155 :chains]))
|
||||
(apply concat)
|
||||
(into #{}))))
|
||||
|
||||
(schema/=> networks
|
||||
[:=>
|
||||
[:cat ?proposal]
|
||||
[:set :string]])
|
||||
|
||||
(defn networks-intersection
|
||||
[proposal supported-networks]
|
||||
(let [proposed-networks (networks proposal)]
|
||||
(networks-utils/networks-intersection proposed-networks
|
||||
supported-networks)))
|
||||
|
||||
(schema/=> networks-intersection
|
||||
[:=>
|
||||
[:cat ?proposal [:sequential :int]]
|
||||
[:sequential :int]])
|
||||
|
||||
(defn required-networks-supported?
|
||||
[proposal supported-networks]
|
||||
(let [supported-namespaces #{:eip155}
|
||||
required-namespaces (get-in proposal [:params :requiredNamespaces])
|
||||
required-networks (get-in required-namespaces [:eip155 :chains])]
|
||||
(when (every? #(contains? supported-namespaces %)
|
||||
(keys required-namespaces))
|
||||
(networks-utils/required-networks-supported? required-networks supported-networks))))
|
||||
|
||||
(schema/=> required-networks-supported?
|
||||
[:=>
|
||||
[:cat ?proposal [:sequential :int]]
|
||||
:boolean])
|
||||
@@ -0,0 +1,87 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.utils.request
|
||||
(:require
|
||||
[schema.core :as schema]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
||||
[utils.datetime :as datetime]))
|
||||
|
||||
(def ^:private ?event
|
||||
[:map
|
||||
[:id :string]
|
||||
[:params
|
||||
[:map
|
||||
[:chainId :string]
|
||||
[:request
|
||||
[:map
|
||||
[:method :string]
|
||||
[:params :any]
|
||||
[:expiryTimestamp :int]]]]]
|
||||
[:verifyContext
|
||||
[:map
|
||||
[:verified
|
||||
[:map
|
||||
[:validation :string]
|
||||
[:origin :string]
|
||||
[:verifyUrl :string]
|
||||
[:isScam {:optional true} :boolean]]]]]])
|
||||
|
||||
(defn expired?
|
||||
[event]
|
||||
(some-> event
|
||||
:params
|
||||
:request
|
||||
:expiryTimestamp
|
||||
datetime/timestamp-expired?))
|
||||
|
||||
(schema/=> expired?
|
||||
[:=> [:cat ?event]
|
||||
[:maybe :boolean]])
|
||||
|
||||
(defn method
|
||||
[event]
|
||||
(get-in event [:params :request :method]))
|
||||
|
||||
(schema/=> method
|
||||
[:=> [:cat ?event]
|
||||
:string])
|
||||
|
||||
(defn chain
|
||||
[event]
|
||||
(-> event
|
||||
(get-in [:params :chainId])
|
||||
networks/eip155->chain-id))
|
||||
|
||||
(schema/=> chain
|
||||
[:=> [:cat ?event]
|
||||
:int])
|
||||
|
||||
(defn screen
|
||||
[event]
|
||||
(let [method-to-screen
|
||||
{constants/wallet-connect-personal-sign-method :screen/wallet-connect.sign-message
|
||||
constants/wallet-connect-eth-sign-typed-method :screen/wallet-connect.sign-message
|
||||
constants/wallet-connect-eth-sign-method :screen/wallet-connect.sign-message
|
||||
constants/wallet-connect-eth-sign-typed-v4-method :screen/wallet-connect.sign-message
|
||||
constants/wallet-connect-eth-send-transaction-method :screen/wallet-connect.send-transaction
|
||||
constants/wallet-connect-eth-sign-transaction-method :screen/wallet-connect.sign-transaction}]
|
||||
(-> event method method-to-screen)))
|
||||
|
||||
(schema/=> screen
|
||||
[:=> [:cat ?event]
|
||||
[:maybe :keyword]])
|
||||
|
||||
(defn params
|
||||
[event]
|
||||
(get-in event [:params :request :params]))
|
||||
|
||||
(schema/=> screen
|
||||
[:=> [:cat ?event]
|
||||
:any])
|
||||
|
||||
(defn url
|
||||
[event]
|
||||
(get-in event [:verifyContext :verified :origin]))
|
||||
|
||||
(schema/=> screen
|
||||
[:=> [:cat ?event]
|
||||
:string])
|
||||
+48
-40
@@ -1,34 +1,53 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.utils.sessions
|
||||
(ns status-im.contexts.wallet.wallet-connect.utils.session
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[promesa.core :as promesa]
|
||||
[react-native.wallet-connect :as wallet-connect]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
||||
[status-im.contexts.wallet.common.utils.account :as account-utils]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.dapp :as dapp-utils]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.rpc :as rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn sdk-session->db-session
|
||||
(defn- dapp-icon
|
||||
[session]
|
||||
(-> session
|
||||
(get-in [:peer :metadata :icons])
|
||||
dapp-utils/best-icon))
|
||||
|
||||
(defn- dapp-url
|
||||
[session]
|
||||
(get-in session [:peer :metadata :url]))
|
||||
|
||||
(defn- dapp-name
|
||||
[session]
|
||||
(-> session
|
||||
(get-in [:peer :metadata :name])
|
||||
(or (dapp-url session))))
|
||||
|
||||
(defn- addresses
|
||||
[session]
|
||||
(get-in session [:namespaces :eip155 :accounts]))
|
||||
|
||||
(defn- chains
|
||||
[session]
|
||||
(get-in session [:namespaces :eip155 :chains]))
|
||||
|
||||
(defn session->db
|
||||
[{:keys [topic expiry pairingTopic] :as session}]
|
||||
{:topic topic
|
||||
:expiry expiry
|
||||
:sessionJson (transforms/clj->json session)
|
||||
:pairingTopic pairingTopic
|
||||
:name (get-in session [:peer :metadata :name])
|
||||
:iconUrl (get-in session [:peer :metadata :icons 0])
|
||||
:url (get-in session [:peer :metadata :url])
|
||||
:accounts (get-in session [:namespaces :eip155 :accounts])
|
||||
:chains (get-in session [:namespaces :eip155 :chains])
|
||||
:name (dapp-name session)
|
||||
:iconUrl (dapp-icon session)
|
||||
:url (dapp-url session)
|
||||
:accounts (addresses session)
|
||||
:chains (chains session)
|
||||
:disconnected false})
|
||||
|
||||
(defn filter-operable-accounts
|
||||
[accounts]
|
||||
(filter #(and (:operable? %)
|
||||
(not (:watch-only? %)))
|
||||
accounts))
|
||||
|
||||
(defn filter-sessions-for-account-addresses
|
||||
(defn filter-for-accounts
|
||||
[account-addresses sessions]
|
||||
(filter (fn [{:keys [accounts]}]
|
||||
(some (fn [account]
|
||||
@@ -40,24 +59,13 @@
|
||||
|
||||
(defn latest-connected-account-address
|
||||
[sessions]
|
||||
(let [all-accounts (->> sessions
|
||||
(sort-by :expiry >)
|
||||
first
|
||||
:accounts)]
|
||||
(-> all-accounts
|
||||
(let [recent-session (->> sessions
|
||||
(sort-by :expiry >)
|
||||
first)]
|
||||
(-> recent-session
|
||||
:accounts
|
||||
first
|
||||
(string/split #":")
|
||||
last)))
|
||||
|
||||
(defn- parse-session-accounts
|
||||
[{:keys [sessionJson] :as session}]
|
||||
(assoc session
|
||||
:accounts
|
||||
(-> sessionJson
|
||||
transforms/json->clj
|
||||
:namespaces
|
||||
:eip155
|
||||
:accounts)))
|
||||
account-utils/from-eip155)))
|
||||
|
||||
(defn- find-inactive-sessions
|
||||
[active-sessions persisted-sessions]
|
||||
@@ -72,20 +80,20 @@
|
||||
(defn get-persisted-sessions
|
||||
[]
|
||||
(-> (rpc/wallet-get-persisted-sessions)
|
||||
(promesa/then #(map parse-session-accounts %))
|
||||
(promesa/then #(map :accounts %))
|
||||
(promesa/catch (fn [err]
|
||||
(throw (ex-info "Failed to get persisted WalletConnect sessions"
|
||||
{:error err
|
||||
:code :error/wc-get-persisted-sessions}))))))
|
||||
|
||||
(defn get-active-sessions
|
||||
[web3-wallet addresses]
|
||||
[web3-wallet account-addresses]
|
||||
(-> (wallet-connect/get-active-sessions web3-wallet)
|
||||
(promesa/then #(->>
|
||||
(transforms/js->clj %)
|
||||
vals
|
||||
(map sdk-session->db-session)
|
||||
(filter-sessions-for-account-addresses addresses)))
|
||||
(map session->db)
|
||||
(filter-for-accounts account-addresses)))
|
||||
(promesa/catch (fn [err]
|
||||
(throw (ex-info "Failed to get active WalletConnect sessions"
|
||||
{:error err
|
||||
@@ -104,10 +112,10 @@
|
||||
:code :error/wc-sync-persisted-sessions}))))))
|
||||
|
||||
(defn get-sessions
|
||||
[web3-wallet addresses online?]
|
||||
[web3-wallet accounts online?]
|
||||
(promesa/let [persisted-sessions (get-persisted-sessions)]
|
||||
(if online?
|
||||
(promesa/let [active-sessions (get-active-sessions web3-wallet addresses)]
|
||||
(promesa/let [active-sessions (get-active-sessions web3-wallet accounts)]
|
||||
(log/info "Got active Wallet Connect sessions" (map :topic active-sessions))
|
||||
;; NOTE: handling the error here, so that if persistance fails, it doesn't affect the active
|
||||
;; sessions
|
||||
@@ -133,7 +141,7 @@
|
||||
(defn approve
|
||||
[{:keys [web3-wallet address session-networks proposal-request]}]
|
||||
(let [{:keys [params id]} proposal-request
|
||||
accounts (-> (partial networks/format-eip155-address address)
|
||||
session-accounts (-> (partial account-utils/to-eip155 address)
|
||||
(map session-networks))]
|
||||
(-> (promesa/let [session
|
||||
(wallet-connect/approve-session
|
||||
@@ -142,7 +150,7 @@
|
||||
:approved-namespaces (->>
|
||||
{:eip155
|
||||
{:chains session-networks
|
||||
:accounts accounts
|
||||
:accounts session-accounts
|
||||
:methods constants/wallet-connect-supported-methods
|
||||
:events constants/wallet-connect-supported-events}}
|
||||
(wallet-connect/build-approved-namespaces params))})]
|
||||
@@ -5,15 +5,14 @@
|
||||
[promesa.core :as promesa]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.rpc :as wallet-rpc]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.request :as session-request]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.rpc :as wallet-connect-rpc]
|
||||
[utils.money :as money]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn transaction-request?
|
||||
[event]
|
||||
(->> (data-store/get-request-method event)
|
||||
(->> (session-request/method event)
|
||||
(contains? #{constants/wallet-connect-eth-send-transaction-method
|
||||
constants/wallet-connect-eth-sign-transaction-method})))
|
||||
|
||||
|
||||
@@ -85,9 +85,8 @@
|
||||
data-chain-id)))
|
||||
|
||||
(defn sign
|
||||
[password address data chain-id-eip155 version]
|
||||
(let [legacy? (= version :v1)
|
||||
chain-id (networks/eip155->chain-id chain-id-eip155)]
|
||||
[password address data chain-id version]
|
||||
(let [legacy? (= version :v1)]
|
||||
(wallet-rpc/safe-sign-typed-data data
|
||||
address
|
||||
password
|
||||
|
||||
@@ -1,29 +1,56 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.utils.uri
|
||||
(:require [react-native.wallet-connect :as wallet-connect]))
|
||||
"Validating and parsing WalletConnect pairing URIs"
|
||||
(:require [malli.util :as malli.util]
|
||||
[react-native.wallet-connect :as wallet-connect]
|
||||
[schema.core :as schema]
|
||||
[utils.datetime :as datetime]))
|
||||
|
||||
(def ?wc-uri
|
||||
[:map
|
||||
[:protocol :string]
|
||||
[:topic :string]
|
||||
[:version :int]
|
||||
[:symKey [:maybe :string]]
|
||||
[:relay :map]
|
||||
[:methods {:optional true} [:maybe [:sequential :any]]]
|
||||
[:expiryTimestamp [:maybe :int]]])
|
||||
|
||||
(defn parse
|
||||
[text-uri]
|
||||
(wallet-connect/parse-uri text-uri))
|
||||
|
||||
(schema/=> parse
|
||||
[:=>
|
||||
[:cat :string]
|
||||
?wc-uri])
|
||||
|
||||
(defn version-supported?
|
||||
[version]
|
||||
(= version 2))
|
||||
[uri]
|
||||
(= 2 (:version uri)))
|
||||
|
||||
(defn- current-timestamp
|
||||
[]
|
||||
(quot (.getTime (js/Date.)) 1000))
|
||||
(schema/=> version-supported?
|
||||
[:=>
|
||||
[:cat ?wc-uri]
|
||||
:boolean])
|
||||
|
||||
(defn timestamp-expired?
|
||||
[expiry-timestamp]
|
||||
(when expiry-timestamp
|
||||
(> (current-timestamp) expiry-timestamp)))
|
||||
(defn expired?
|
||||
[uri]
|
||||
(some-> uri
|
||||
:expiryTimestamp
|
||||
datetime/timestamp-expired?))
|
||||
|
||||
(defn valid-wc-uri?
|
||||
[parsed-uri]
|
||||
(let [{:keys [topic version]} parsed-uri]
|
||||
(and (seq topic)
|
||||
(number? version))))
|
||||
(schema/=> expired?
|
||||
[:=>
|
||||
[:cat ?wc-uri]
|
||||
[:maybe :boolean]])
|
||||
|
||||
(defn valid-uri?
|
||||
"Check if the uri is in the wallet-connect format.
|
||||
At this stage, the uri might be expired or from an unsupported version"
|
||||
[s]
|
||||
(-> s
|
||||
wallet-connect/parse-uri
|
||||
valid-wc-uri?))
|
||||
(defn valid?
|
||||
[uri]
|
||||
(let [{:keys [topic version]} uri]
|
||||
(boolean (and (seq topic)
|
||||
(number? version)))))
|
||||
|
||||
(schema/=> valid?
|
||||
[:=>
|
||||
[:cat (malli.util/optional-keys ?wc-uri)]
|
||||
[:maybe :boolean]])
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im.subs.wallet.dapps.proposals
|
||||
(:require [re-frame.core :as rf]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.proposal :as proposal]
|
||||
[utils.string]))
|
||||
|
||||
(rf/reg-sub
|
||||
@@ -15,17 +14,22 @@
|
||||
:-> :session-networks)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposer
|
||||
:wallet-connect/session-proposer-name
|
||||
:<- [:wallet-connect/current-proposal-request]
|
||||
(fn [proposal]
|
||||
(-> proposal :params :proposer)))
|
||||
(proposal/dapp-name proposal)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposer-name
|
||||
:<- [:wallet-connect/session-proposer]
|
||||
(fn [proposer]
|
||||
(let [{:keys [name url]} (-> proposer :metadata)]
|
||||
(data-store/compute-dapp-name name url))))
|
||||
:wallet-connect/session-proposer-icon
|
||||
:<- [:wallet-connect/current-proposal-request]
|
||||
(fn [proposal]
|
||||
(proposal/dapp-icon proposal)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposer-url
|
||||
:<- [:wallet-connect/current-proposal-request]
|
||||
(fn [proposal]
|
||||
(proposal/dapp-url proposal)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposal-network-details
|
||||
|
||||
@@ -77,22 +77,6 @@
|
||||
:origin "https://lab.web3modal.com"
|
||||
:isScam false}}}})
|
||||
|
||||
(h/deftest-sub :wallet-connect/session-proposer
|
||||
[sub-name]
|
||||
(testing "Return the session proposer public key and metadata"
|
||||
(swap! rf-db/app-db
|
||||
assoc-in
|
||||
[:wallet-connect/current-proposal :request]
|
||||
sample-session)
|
||||
|
||||
(let [proposer (rf/sub [sub-name])]
|
||||
(is (= (-> proposer :publicKey)
|
||||
(-> sample-session :params :proposer :publicKey)))
|
||||
|
||||
(is (= (-> proposer :metadata :url)
|
||||
|
||||
(-> sample-session :params :proposer :metadata :url))))))
|
||||
|
||||
(h/deftest-sub :wallet-connect/session-proposer-name
|
||||
[sub-name]
|
||||
(testing "Return only the name of the session proposer"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||
data-store]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.request :as session-request]
|
||||
[status-im.contexts.wallet.wallet-connect.utils.typed-data :as typed-data]
|
||||
[utils.string]))
|
||||
|
||||
@@ -23,7 +24,7 @@
|
||||
(fn [request]
|
||||
(-> request
|
||||
:event
|
||||
data-store/get-request-method)))
|
||||
session-request/method)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/current-request-account-details
|
||||
@@ -40,15 +41,17 @@
|
||||
:<- [:wallet-connect/current-request]
|
||||
:<- [:wallet-connect/sessions]
|
||||
(fn [[request sessions]]
|
||||
(data-store/get-current-request-dapp request sessions)))
|
||||
(-> request
|
||||
:event
|
||||
(data-store/get-current-request-dapp sessions))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/chain-id
|
||||
:<- [:wallet-connect/current-request]
|
||||
(fn [request]
|
||||
(-> request
|
||||
(get-in [:event :params :chainId])
|
||||
(networks/eip155->chain-id))))
|
||||
:event
|
||||
session-request/chain)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/current-request-network
|
||||
|
||||
@@ -325,3 +325,10 @@
|
||||
(def ^:const go-default-time
|
||||
"Zero value for golang's time var"
|
||||
"0001-01-01T00:00:00Z")
|
||||
|
||||
(defn timestamp-expired?
|
||||
[ms]
|
||||
(-> ms
|
||||
(* 1000)
|
||||
to-date
|
||||
(t/before? (now))))
|
||||
|
||||
Reference in New Issue
Block a user