remove dev-server and extensions for v1

This commit is contained in:
yenda 2019-08-08 18:19:49 +02:00
parent d7cd2b8a74
commit d61fffb021
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
55 changed files with 19 additions and 2959 deletions

View File

@ -13,7 +13,6 @@
hickory {:mvn/version "0.7.1"}
cljs-bean {:mvn/version "1.3.0"}
com.cognitect/transit-cljs {:mvn/version "0.8.248"}
status-im/pluto {:mvn/version "iteration-4-9"}
mvxcvi/alphabase {:mvn/version "1.0.0"}
rasom/cljs-react-navigation {:mvn/version "0.1.4"}}

View File

@ -102,8 +102,6 @@ https://repo.clojars.org/ring/ring-core/1.5.1/ring-core-1.5.1
https://repo.clojars.org/ring/ring-defaults/0.1.5/ring-defaults-0.1.5
https://repo.clojars.org/ring/ring-headers/0.1.3/ring-headers-0.1.3
https://repo.clojars.org/ring/ring-ssl/0.2.1/ring-ssl-0.2.1
https://repo.clojars.org/slingshot/slingshot/0.12.2/slingshot-0.12.2
https://repo.clojars.org/status-im/pluto/iteration-4-9/pluto-iteration-4-9
https://repo.clojars.org/status-im/re-frame/0.10.5/re-frame-0.10.5
https://repo.clojars.org/status-im/timbre/4.10.0-2-status/timbre-4.10.0-2-status
https://repo.clojars.org/table/table/0.4.0/table-0.4.0

View File

@ -20,7 +20,6 @@
[hickory "0.7.1"]
[cljs-bean "1.3.0"]
[com.cognitect/transit-cljs "0.8.248"]
[status-im/pluto "iteration-4-9"]
[mvxcvi/alphabase "1.0.0"]
[rasom/cljs-react-navigation "0.1.4"]]
:plugins [[rasom/lein-githooks "0.1.5"]
@ -133,27 +132,7 @@
"status_im.network.events"
"status_im.network.subs"
"status_im.network.core"}
:output-to "status-modules/cljs/network-raw.js"}
:extensions {:entries #{"status_im.extensions.ui.db"
"status_im.extensions.ui.add.events"
"status_im.extensions.ui.add.views"
"status_im.extensions.ui.add.styles"
"status_im.extensions.ui.views"
"status_im.extensions.ui.styles"
"status_im.extensions.events"
"status_im.extensions.registry"
"status_im.extensions.core"
"status_im.extensions.module"
"status_im.extensions.capacities.events"
"status_im.extensions.capacities.subs"
"status_im.extensions.capacities.camera.events"
"status_im.extensions.capacities.camera.views"
"status_im.extensions.capacities.components"
"status_im.extensions.capacities.views"
"status_im.extensions.capacities.ethereum"
"status_im.extensions.capacities.map"
"status_im.extensions.capacities.network"}
:output-to "status-modules/cljs/extensions-raw.js"}}}
:output-to "status-modules/cljs/network-raw.js"}}}
:warning-handlers [status-im.utils.build/warning-handler]}
:android
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src" "env/prod" "prod"]
@ -183,27 +162,7 @@
"status_im.network.events"
"status_im.network.subs"
"status_im.network.core"}
:output-to "status-modules/cljs/network-raw.js"}
:extensions {:entries #{"status_im.extensions.ui.db"
"status_im.extensions.ui.add.events"
"status_im.extensions.ui.add.views"
"status_im.extensions.ui.add.styles"
"status_im.extensions.ui.views"
"status_im.extensions.ui.styles"
"status_im.extensions.events"
"status_im.extensions.registry"
"status_im.extensions.core"
"status_im.extensions.module"
"status_im.extensions.capacities.events"
"status_im.extensions.capacities.subs"
"status_im.extensions.capacities.camera.events"
"status_im.extensions.capacities.camera.views"
"status_im.extensions.capacities.components"
"status_im.extensions.capacities.views"
"status_im.extensions.capacities.ethereum"
"status_im.extensions.capacities.map"
"status_im.extensions.capacities.network"}
:output-to "status-modules/cljs/extensions-raw.js"}}}
:output-to "status-modules/cljs/network-raw.js"}}}
:warning-handlers [status-im.utils.build/warning-handler]}
:desktop
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/desktop" "src" "env/prod" "prod"]
@ -231,25 +190,5 @@
"status_im.network.events"
"status_im.network.subs"
"status_im.network.core"}
:output-to "status-modules/cljs/network-raw.js"}
:extensions {:entries #{"status_im.extensions.ui.db"
"status_im.extensions.ui.add.events"
"status_im.extensions.ui.add.views"
"status_im.extensions.ui.add.styles"
"status_im.extensions.ui.views"
"status_im.extensions.ui.styles"
"status_im.extensions.events"
"status_im.extensions.registry"
"status_im.extensions.core"
"status_im.extensions.module"
"status_im.extensions.capacities.events"
"status_im.extensions.capacities.subs"
"status_im.extensions.capacities.camera.events"
"status_im.extensions.capacities.camera.views"
"status_im.extensions.capacities.components"
"status_im.extensions.capacities.views"
"status_im.extensions.capacities.ethereum"
"status_im.extensions.capacities.map"
"status_im.extensions.capacities.network"}
:output-to "status-modules/cljs/extensions-raw.js"}}}
:output-to "status-modules/cljs/network-raw.js"}}}
:warning-handlers [status-im.utils.build/warning-handler]}}}}})

View File

@ -80,10 +80,6 @@ StatusAPI.prototype.getContactCode = function () {
return sendAPIrequest('contact-code');
};
StatusAPI.prototype.installExtension = function (uri) {
return sendAPIrequest('install-extension', {uri: uri});
};
var StatusHttpProvider = function () {};
StatusHttpProvider.prototype.isStatus = true;

View File

@ -111,10 +111,6 @@ StatusAPI.prototype.getContactCode = function () {
return sendAPIrequest('contact-code');
};
StatusAPI.prototype.installExtension = function (uri) {
return sendAPIrequest('install-extension', {uri: uri});
};
var ReadOnlyProvider = function () {};
ReadOnlyProvider.prototype.isStatus = true;
@ -221,4 +217,4 @@ ReadOnlyBetaProvider.prototype.send = function (method, params = []) {
console.log("ReadOnlyProvider");
ethereum = new ReadOnlyProvider();
console.log("ReadOnlyBetaProvider");
ethereumBeta = new ReadOnlyBetaProvider();
ethereumBeta = new ReadOnlyBetaProvider();

View File

@ -2,7 +2,6 @@
(:require [status-im.constants :as constants]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.extensions.module :as extensions.module]
[status-im.i18n :as i18n]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.ui.screens.navigation :as navigation]
@ -15,8 +14,6 @@
(def supported-permissions
{constants/dapp-permission-qr-code {:yield-control? true
:allowed? true}
constants/dapp-permission-install-extension {:yield-control? true
:allowed? true}
constants/dapp-permission-contact-code {:title (i18n/label :t/wants-to-access-profile)
:description (i18n/label :t/your-contact-code)
:icon :main-icons/profile}
@ -27,12 +24,6 @@
(fx/defn permission-yield-control
[{:keys [db] :as cofx} dapp-name permission message-id params]
(cond
(= permission constants/dapp-permission-install-extension)
(fx/merge cofx
(extensions.module/load (:uri params) true)
(send-response-to-bridge permission message-id true nil)
(process-next-permission dapp-name))
(= permission constants/dapp-permission-qr-code)
(fx/merge (assoc-in cofx [:db :browser/options :yielding-control?] true)
(qr-scanner/scan-qr-code {}

View File

@ -68,7 +68,3 @@
"Function which takes original parameters + cofx map and returns new map of parameters")
(enhance-receive-parameters [this parameters cofx]
"Function which takes original parameters + cofx map and returns new map of parameters"))
(defprotocol Extension
"Protocol for defining extension"
(extension-id [this]))

View File

@ -13,9 +13,7 @@
(let [command-path (commands/command-id type)
new-parameter-map (and (satisfies? protocol/EnhancedParameters type)
(protocol/enhance-send-parameters type parameter-map cofx))
params (merge (or new-parameter-map parameter-map)
(when (satisfies? protocol/Extension type)
{:extension-id (protocol/extension-id type)}))]
params (or new-parameter-map parameter-map)]
{:chat-id chat-id
:content-type constants/content-type-command
:content {:chat-id chat-id
@ -50,4 +48,4 @@
#(protocol/on-send type (commands/enrich-command-message-for-events db command-message) %)
(commands.input/set-command-reference nil)
(commands.input/clean-custom-params)
(chat.message/send-message command-message))))
(chat.message/send-message command-message))))

View File

@ -269,7 +269,6 @@
(def ^:const dapp-permission-contact-code "contact-code")
(def ^:const dapp-permission-web3 "web3")
(def ^:const dapp-permission-qr-code "qr-code")
(def ^:const dapp-permission-install-extension "install-extension")
(def ^:const api-response "api-response")
(def ^:const api-request "api-request")
(def ^:const history-state-changed "history-state-changed")

View File

@ -1,36 +0,0 @@
(ns status-im.dev-server.core
(:require [status-im.ui.components.react :as react]
[status-im.utils.platform :as platform]
[status-im.utils.types :as types]
[taoensso.timbre :as log]
[re-frame.core :as re-frame]))
(defonce port 5561)
(defonce server-name (if platform/ios?
"Status iOS"
"Status Android"))
(defn respond! [request-id status-code data]
(.respond (react/http-bridge)
request-id
status-code
"application/json"
(types/clj->json data)))
(defn start! []
(.start (react/http-bridge)
port
server-name
(fn [req]
(try
(let [{:keys [requestId url type postData]} (js->clj req :keywordize-keys true)
data (if (string? postData)
(-> (.parse js/JSON postData)
(js->clj :keywordize-keys true))
postData)]
(re-frame/dispatch [:process-http-request requestId url type data]))
(catch js/Error e
(log/debug "Error: " e))))))
(defn stop! []
(.stop (react/http-bridge)))

View File

@ -1,38 +0,0 @@
(ns status-im.dev-server.events
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.dev-server.core :as dev-server.core]
[status-im.models.dev-server :as models.dev-server]
[status-im.utils.handlers :as handlers]))
;; FX
(re-frame/reg-fx
:dev-server/start
(fn []
(dev-server.core/start!)))
(re-frame/reg-fx
:dev-server/stop
(fn []
(dev-server.core/stop!)))
(re-frame/reg-fx
:dev-server/respond
(fn [[request-id status-code data]]
(dev-server.core/respond! request-id status-code data)))
;; Handlers
(handlers/register-handler-fx
:process-http-request
[(re-frame/inject-cofx :random-id-generator)]
(fn [cofx [_ request-id url type data]]
(try
(models.dev-server/process-request! {:cofx cofx
:request-id request-id
:url (rest (string/split url "/"))
:type (keyword type)
:data data})
(catch js/Error e
{:dev-server/respond [request-id 400 {:message (str "Unsupported operation: " e)}]}))))

View File

@ -1277,8 +1277,8 @@
(handlers/register-handler-fx
:browser.ui/open-url
(fn [cofx [_ url extension-params]]
(browser/open-url cofx (or (:url extension-params) url))))
(fn [cofx [_ url]]
(browser/open-url cofx url)))
(handlers/register-handler-fx
:browser.ui/open-modal-chat-button-pressed

View File

@ -1,62 +0,0 @@
(ns status-im.extensions.capacities.camera.events
(:require [re-frame.core :as re-frame]
[status-im.utils.fx :as fx]
[status-im.extensions.capacities.camera.views :as ext-views]
[status-im.ui.components.list-selection :as list-selection]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.handlers :as handlers]))
;; Common
(handlers/register-handler-fx
:extensions/camera-cancel
(fn [_ [_ _ {{:keys [on-failure]} :data}]]
(when on-failure
(re-frame/dispatch (on-failure {:result "user cancelled"})))))
(handlers/register-handler-fx
:extensions/camera-denied
(fn [_ [_ {{:keys [on-failure]} :data}]]
(when on-failure
(re-frame/dispatch (on-failure {:result "user denied access to camera"})))))
;; Photo taker\picker
(handlers/register-handler-fx
:extensions/camera-error
(fn [cofx [_ error {:keys [on-failure]}]]
(when on-failure
(on-failure {:result error}))))
(handlers/register-handler-fx
:extensions/camera-picture-taken
(fn [cofx [_ data {{:keys [on-success]} :data back? :back?}]]
(fx/merge cofx
(on-success {:result data})
(when back?
(navigation/navigate-back)))))
(handlers/register-handler-fx
:extensions/camera-picture
(fn [_ [_ _ params]]
(list-selection/show (ext-views/pick-or-take-picture-list-selection {:data params}))
{}))
;; QR code scanner
(handlers/register-handler-fx
:extensions/camera-qr-code-scanned
(fn [cofx [_ _ qr-code {{:keys [on-success]} :data}]]
(fx/merge cofx
(on-success {:result qr-code})
(navigation/navigate-back))))
(handlers/register-handler-fx
:extensions/camera-qr-code
(fn [{:keys [db] :as cofx} [_ _ {:keys [on-success on-failure]}]]
(qr-scanner/scan-qr-code cofx {:deny-handler :extensions/camera-denied}
{:handler :extensions/camera-qr-code-scanned
:cancel-handler :extensions/camera-cancel
:data {:on-success on-success
:on-failure on-failure}})))

View File

@ -1,65 +0,0 @@
(ns status-im.extensions.capacities.camera.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.ui.components.camera :as camera]
[status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.toolbar.actions :as actions]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.i18n :as i18n]
[status-im.ui.screens.profile.photo-capture.styles :as styles]
[status-im.utils.image-processing :as image-processing]))
(def default-max-size 1024)
(defn- process-image-and-finish [path context]
(let [on-success #(re-frame/dispatch [:extensions/camera-picture-taken % context])
on-error #(re-frame/dispatch [:extensions/camera-error %2 context])]
(image-processing/img->base64 path on-success on-error default-max-size default-max-size)))
(defview take-picture []
(letsubs [context [:get-screen-params]
camera-ref (reagent/atom false)]
[react/view styles/container
[status-bar/status-bar]
[toolbar/toolbar nil
[toolbar/nav-button (actions/back
#(do
(re-frame/dispatch [:extensions/camera-cancel context])
(re-frame/dispatch [:navigate-back])))]
[toolbar/content-title (i18n/label :t/extensions-camera-send-picture)]]
[camera/camera {:style {:flex 1}
:aspect (:fill camera/aspects)
:captureTarget (:disk camera/capture-targets)
:ref #(reset! camera-ref %)}]
[react/view styles/button-container
[react/view styles/button
[react/touchable-highlight {:on-press (fn []
(let [camera @camera-ref]
(-> (.capture camera)
(.then #(process-image-and-finish (.-path %) context))
(.catch #(re-frame/dispatch [:extensions/camera-error % context])))))}
[react/view
[icons/icon :main-icons/camera {:color :white}]]]]]]))
;TODO image picker doesn't notify when the user cancel image selection
; in this case we cannot notify cancel to extension
(defn- open-image-picker [context]
(react/show-image-picker
(fn [image]
(let [path (get (js->clj image) "path")]
(process-image-and-finish path context)))
"photo"))
(defn pick-or-take-picture-list-selection [context]
{:title (i18n/label :t/extensions-camera-send-picture)
:options [{:label (i18n/label :t/image-source-gallery)
:action #(open-image-picker context)}
{:label (i18n/label :t/image-source-make-photo)
:action (fn []
(re-frame/dispatch [:request-permissions {:permissions [:camera :write-external-storage]
:on-allowed #(re-frame/dispatch [:navigate-to :take-picture (merge context {:back? true})])
:on-denied #(re-frame/dispatch [:extensions/camera-denied context])}]))}]
:on-cancel #(re-frame/dispatch [:extensions/camera-cancel context])})

View File

@ -1,176 +0,0 @@
(ns status-im.extensions.capacities.components
(:require
[clojure.string :as string]
[reagent.core :as reagent]
[status-im.ui.components.react :as react]
[status-im.chat.commands.impl.transactions :as transactions]
[status-im.ui.components.button.view :as button]
[re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.utils.platform :as platform]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.checkbox.view :as checkbox]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.tooltip.views :as tooltip]
[status-im.ui.components.text-input.styles :as styles]
[status-im.extensions.capacities.map :as map-component]))
(defn button [{:keys [on-click enabled disabled] :as m} label]
[button/secondary-button (merge {:disabled? (or (when (contains? m :enabled) (or (nil? enabled) (false? enabled))) disabled)}
(when on-click {:on-press #(on-click {})})) label])
(defn on-input-change-text [on-change value]
(on-change {:value value}))
(defn- on-input-change-text-delay [current on-change value delay]
;; If an input change handler has been already scheduled cancel it.
(when-let [id @current]
(js/clearTimeout id))
(reset! current (js/setTimeout #(on-input-change-text on-change value) delay)))
(defn- in-range [n start end]
(or (string/blank? n) (and (nil? start) (nil? end)) (and (< n end) (> n start))))
(defn input [{:keys [keyboard-type style error min max on-change change-delay placeholder placeholder-text-color selection-color
auto-focus on-submit default-value]}]
(let [input-range (reagent/atom nil)]
(fn []
[react/view
[react/text-input (merge {:placeholder placeholder}
{:on-change-text #(reset! input-range %)}
(when placeholder-text-color {:placeholder-text-color placeholder-text-color})
(when selection-color {:selection-color selection-color})
(when style {:style style})
(when keyboard-type {:keyboard-type keyboard-type})
(when auto-focus {:auto-focus auto-focus})
(when default-value {:default-value default-value})
(when on-submit
{:on-submit-editing #(on-submit {})})
(when on-change
{:on-change-text
(if change-delay
(let [current (atom nil)]
#(on-input-change-text-delay current on-change % change-delay))
#(on-input-change-text on-change %))}))]
(when-not (in-range @input-range, min, max)
[tooltip/tooltip (i18n/label :t/invalid-range {:min min :max max}) styles/error])
(when error
[tooltip/tooltip error (styles/error error)])])))
(defn touchable-opacity [{:keys [style on-press]} & children]
(into [react/touchable-opacity (merge (when on-press {:on-press #(on-press {})})
(when style {:style style}))] children))
(defn image [{:keys [source uri style]}]
[react/image (merge {:style (merge {:width 100 :height 100} style)} {:source (if source source {:uri uri})})])
(defn link [{:keys [uri style open-in text]}]
[react/text (merge {:style {:color colors/white
:text-decoration-line :underline}
:on-press (case open-in
:device #(.openURL (react/linking) uri)
:status #(re-frame/dispatch [:browser.ui/open-url uri])
#(re-frame/dispatch [:browser.ui/message-link-pressed uri]))}
(when style {:style style}))
(or text uri)])
(defn map-link
"create a link-view which opens native map/navigation app with marker and label"
[{:keys [text lat lng style]}]
(let [uri (cond
platform/ios? (str "http://maps.apple.com/?q=" (js/encodeURIComponent text) "&ll=" lat "," lng)
platform/android? (str "geo:0,0?q=" lat "," lng "(" (js/encodeURIComponent text) ")")
:else (str "http://www.openstreetmap.org/?mlat=" lat "&mlon=" lng))]
(link {:uri uri
:text text
:style style
:open-in :device})))
(defn flat-list [{:keys [key data item-view]}]
[list/flat-list {:data data :key-fn (or key (fn [_ i] (str i))) :render-fn item-view}])
(defn checkbox [{:keys [on-change checked]}]
[react/view {:style {:background-color colors/white}}
[checkbox/checkbox {:checked? checked
:style {:padding 0}
:on-value-change #(on-change {:value %})}]])
(defn activity-indicator-size [k]
(condp = k
:small "small"
:large "large"
nil))
(defn activity-indicator [{:keys [animating hides-when-stopped color size]}]
[react/activity-indicator (merge (when animating {:animating animating})
(when hides-when-stopped {:hidesWhenStopped hides-when-stopped})
(when color {:color color})
(when-let [size' (activity-indicator-size size)] {:size size'}))])
(defn picker [{:keys [style on-change selected enabled data]}]
[react/picker {:style style :on-change #(on-change {:value %}) :selected selected :enabled enabled :data data}])
(defn- wrap-text-child [o]
(if (ifn? o) o (str o)))
(defn text [o & children]
(if (map? o)
(into [react/text o] (map wrap-text-child children))
(into [react/text {} o] (map wrap-text-child children))))
(defn- wrap-view-child [child]
(if (vector? child) child [text {} child]))
(defn abstract-view [type o & children]
(if (map? o)
(into [type o] (map wrap-view-child children))
(into [type {} (wrap-view-child o)] (map wrap-view-child children))))
(defn view [o & children]
(apply abstract-view react/view o children))
(defn scroll-view [o & children]
(apply abstract-view react/scroll-view o children))
(defn keyboard-avoiding-view [o & children]
(apply abstract-view react/keyboard-avoiding-view o children))
(defn icon [{:keys [key] :as o}]
[icons/icon key o])
;;CAPACITIES
(def all
{'view {:data view}
'scroll-view {:data scroll-view :properties {:keyboard-should-persist-taps :keyword :content-container-style :map}}
'keyboard-avoiding-view {:data react/keyboard-avoiding-view}
'text {:data text}
'touchable-opacity {:data touchable-opacity :properties {:on-press :event}}
'icon {:data icon :properties {:key :keyword :color :any}}
'image {:data image :properties {:uri :string :source :string}}
'input {:data input :properties {:on-change :event :error :string :placeholder :string :keyboard-type :keyword
:change-delay? :number :placeholder-text-color :any :selection-color :any
:auto-focus? :boolean :min :number :max :number :on-submit :event :default-value :any}}
'button {:data button :properties {:enabled :boolean :disabled :boolean :on-click :event}}
'link {:data link :properties {:uri :string :text? :string :open-in? {:one-of #{:device :status}}}}
'list {:data flat-list :properties {:data :vector :item-view :view :key? :keyword}}
'checkbox {:data checkbox :properties {:on-change :event :checked :boolean}}
'activity-indicator {:data activity-indicator :properties {:animating :boolean :color :string :size :keyword :hides-when-stopped :boolean}}
'picker {:data picker :properties {:on-change :event :selected :string :enabled :boolean :data :vector}}
'nft-token-viewer {:data transactions/nft-token :properties {:token :string}}
'transaction-status {:data transactions/transaction-status :properties {:outgoing :string :tx-hash :string}}
'map {:data map-component/map-webview
:properties {:marker {:lng :number
:lat :number
:boundingbox {:lng1 :number
:lat1 :number
:lng2 :number
:lat2 :number}}
:fly? :boolean
:interactive? :boolean
:on-change :event}}
'map-link {:data map-link :properties {:text :string :lng :any :lat :any}}})

View File

@ -1,472 +0,0 @@
(ns status-im.extensions.capacities.ethereum
(:require [clojure.string :as string]
[status-im.constants :as constants]
[status-im.ethereum.abi-spec :as abi-spec]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.ens :as ens]
[status-im.native-module.core :as status]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]
[status-im.utils.handlers :as handlers]
[status-im.utils.types :as types]
[status-im.signing.core :as signing]))
(handlers/register-handler-fx
:extensions/wallet-ui-on-success
(fn [_ [_ on-success result]]
(when on-success (on-success {:value result}))))
(handlers/register-handler-fx
:extensions/wallet-ui-on-failure
(fn [_ [_ on-failure message]]
(when on-failure (on-failure {:value message}))))
(defn- wrap-with-resolution
"function responsible to resolve ens taken from argument
and call the specified function with resolved address"
[db arguments address-keyword f]
(let [address (get arguments address-keyword)
;; currently we only support one ens for address
first-address (if (vector? address)
(first address)
address)]
(if (ens/is-valid-eth-name? first-address)
(let [chain (ethereum/chain-keyword db)
registry (get ens/ens-registries chain)]
(ens/get-addr registry first-address
#(f db (assoc arguments address-keyword %))))
(f db arguments))))
(defn- execute-send-transaction [db {:keys [method params on-success on-failure] :as arguments}]
(signing/sign {:db db} {:tx-obj (assoc (select-keys arguments [:to :gas :gas-price :value :nonce])
:data (when (and method params) (abi-spec/encode method params)))
:on-result [:extensions/wallet-ui-on-success on-success]
:on-error [:extensions/wallet-ui-on-failure on-failure]}))
(handlers/register-handler-fx
:extensions/ethereum-send-transaction
(fn [{db :db} [_ _ arguments]]
(wrap-with-resolution db arguments :to execute-send-transaction)))
(defn- rpc-args [method params]
{:jsonrpc "2.0"
:method method
:params params})
(defn- rpc-dispatch [error result f on-success on-failure]
(when result
(on-success {:value (f result)}))
(when (and error on-failure)
(on-failure {:value error})))
(defn- rpc-handler [o f on-success on-failure]
(let [{:keys [error result]} (types/json->clj o)]
(rpc-dispatch error result f on-success on-failure)))
(defn- rpc-call [method params f {:keys [on-success on-failure]}]
(let [payload (types/clj->json (rpc-args method params))]
(status/call-private-rpc payload #(rpc-handler % f on-success on-failure))))
(defn parse-call-result [o outputs]
(let [result (get (js->clj o) "result")]
(cond
(= "0x" result) nil
(and outputs result)
(abi-spec/decode result outputs)
:else result)))
(defn- execute-ethcall [_ {:keys [to method params outputs on-success on-failure]}]
(let [tx-object {:to to :data (when method (abi-spec/encode method params))}]
{:browser/call-rpc [(rpc-args "eth_call" [tx-object "latest"])
#(rpc-dispatch %1 %2 (fn [o] (parse-call-result o outputs)) on-success on-failure)]}))
(handlers/register-handler-fx
:extensions/ethereum-call
(fn [{db :db} [_ _ arguments]]
(wrap-with-resolution db arguments :to execute-ethcall)))
(handlers/register-handler-fx
:extensions/ethereum-erc20-total-supply
(fn [{db :db} [_ _ {:keys [contract on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "totalSupply()"
:outputs ["uint256"]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-ethcall))))
(handlers/register-handler-fx
:extensions/ethereum-erc20-balance-of
(fn [{db :db} [_ _ {:keys [contract token-owner on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "balanceOf(address)"
:params [token-owner]
:outputs ["uint256"]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-ethcall))))
(handlers/register-handler-fx
:extensions/ethereum-erc20-allowance
(fn [{db :db} [_ _ {:keys [contract token-owner spender on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "allowance(address,address)"
:params [token-owner spender]
:outputs ["uint256"]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-ethcall))))
(handlers/register-handler-fx
:extensions/ethereum-erc20-transfer
(fn [{db :db} [_ _ {:keys [contract to value on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "transfer(address,uint256)"
:params [to value]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-send-transaction))))
(handlers/register-handler-fx
:extensions/ethereum-erc20-transfer-from
(fn [{db :db} [_ _ {:keys [contract from to value on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "transferFrom(address,address,uint256)"
:params [from to value]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-send-transaction))))
(handlers/register-handler-fx
:extensions/ethereum-erc20-approve
(fn [{db :db} [_ _ {:keys [contract spender value on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "approve(address,uint256)"
:params [spender value]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-send-transaction))))
(handlers/register-handler-fx
:extensions/ethereum-erc721-owner-of
(fn [{db :db} [_ _ {:keys [contract token-id on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "ownerOf(uint256)"
:params [token-id]
:outputs ["address"]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-ethcall))))
(handlers/register-handler-fx
:extensions/ethereum-erc721-is-approved-for-all
(fn [{db :db} [_ _ {:keys [contract owner operator on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "isApprovedForAll(address,address)"
:params [owner operator]
:outputs ["bool"]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-ethcall))))
(handlers/register-handler-fx
:extensions/ethereum-erc721-get-approved
(fn [{db :db} [_ _ {:keys [contract token-id on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "getApproved(uint256)"
:params [token-id]
:outputs ["address"]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-ethcall))))
(handlers/register-handler-fx
:extensions/ethereum-erc721-set-approval-for-all
(fn [{db :db} [_ _ {:keys [contract to approved on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method "setApprovalForAll(address,bool)"
:params [to approved]
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-send-transaction))))
(handlers/register-handler-fx
:extensions/ethereum-erc721-safe-transfer-from
(fn [{db :db} [_ _ {:keys [contract from to token-id data on-success on-failure]}]]
(let [json-rpc-args {:to contract
:method (if data
"safeTransferFrom(address,address,uint256,bytes)"
"safeTransferFrom(address,address,uint256)")
:params (if data
[from to token-id data]
[from to token-id])
:on-success on-success
:on-failure on-failure}]
(wrap-with-resolution db json-rpc-args :to execute-send-transaction))))
(defn- event-topic-enc [event params]
(let [eventid (str event "(" (string/join "," params) ")")]
(ethereum/sha3 eventid)))
(defn- get-no-indexed
"Return a vector without indexed elements"
[X indexed]
(as-> (into [] (take (count X) (range))) $
(zipmap $ X)
(into [] (vals (apply dissoc $ indexed)))))
(defn- get-indexed
"Return a vector with indexed elements"
[X indexed]
(let [keys (into [] (take (count X) (range)))]
(mapv #((zipmap keys X) %) indexed)))
(defn- get-hint
"Return the hint with the specified event (Topic0) from a vector of event hints given by the user"
[hints first-topic]
(as-> hints $
(mapv #(event-topic-enc (% :event) (% :params)) $)
(.indexOf $ first-topic)
(get hints $)))
(defn- decode-data
"Return a map with all data params decoded"
[data hint]
(let [indexes (hint :indexed)
params (get-no-indexed (hint :params) indexes)
;; Exclude indexed params and names from decode in data,
;; these are decoded in topics
names (mapv keyword (get-no-indexed (hint :names) indexes))
data-values (mapv (partial apply str) (partition 64 (string/replace-first data #"0x" "")))]
(zipmap names (mapv abi-spec/hex-to-value data-values params))))
(defn- decode-topics
"This assumes that Topic 0 is filtered and return a map with all topics decoded"
[topics hint]
;; Solidity indexed event params may number up to 3 (max 4 Topics)
(zipmap [:topic1 :topic2 :topic3] (mapv abi-spec/hex-to-value topics (get-indexed (hint :params) (hint :indexed)))))
(defn- flatten-input
"Flatten the input of event provided by an developer of extensions and return a 1 depth vector"
[input]
(into [] (flatten input)))
(defn parse-log [events-hints {:keys [address transactionHash blockHash transactionIndex topics blockNumber logIndex removed data]}]
(merge {:data data
:topics topics
:address address
:removed removed}
;; 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 transactionIndex {:transaction-index (abi-spec/hex-to-number transactionIndex)})
(when transactionHash {:transaction-hash transactionHash})
(when blockHash {:block-hash blockHash})
(when blockNumber {:block-number (abi-spec/hex-to-number blockNumber)})))
(defn- parse-receipt [events-hints m]
(when m
(let [{:keys [status transactionHash transactionIndex blockHash blockNumber from to cumulativeGasUsed gasUsed contractAddress logs logsBloom]} m]
{:status (= 1 (abi-spec/hex-to-number status))
:transaction-hash transactionHash
:transaction-index (abi-spec/hex-to-number transactionIndex)
:block-hash blockHash
:block-number (abi-spec/hex-to-number blockNumber)
:from from
:to to
:cumulative-gas-used (abi-spec/hex-to-number cumulativeGasUsed)
:gas-used (abi-spec/hex-to-number gasUsed)
:contract-address contractAddress
:logs (map #(parse-log events-hints %) logs)
:logs-bloom logsBloom})))
(handlers/register-handler-fx
:extensions/ethereum-transaction-receipt
(fn [_ [_ _ {:keys [value] :as m}]]
(rpc-call constants/web3-transaction-receipt [value] #(parse-receipt (flatten-input (:topics-hints m)) %) m)))
(handlers/register-handler-fx
:extensions/ethereum-await-transaction-receipt
(fn [_ [_ _ {:keys [value interval on-success] :as m}]]
(let [id (atom nil)
new-on-success (fn [o] (js/clearInterval @id) (on-success o))]
(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))
nil)))
(defn- types-mapping [type]
(cond
(= "bool" type) :bool
(string/starts-with? type "uint") :uint
(string/starts-with? type "int") :int
(string/starts-with? type "address") :address
(string/starts-with? type "bytes") :bytes
(string/starts-with? type "fixed") :bytes
:else :bytes))
(defn- values-topic-enc [type values]
(mapv #(str "0x" (abi-spec/enc {:type (types-mapping type) :value %})) values))
(defn- generate-topic [t]
(cond
(or (nil? t) (string? t)) t ;; nil topic ;; immediate topic (extension encode topic by its own) ;; vector of immediate topics
(vector? t) (mapv generate-topic t) ;; descend in vector elements
(map? t) ;; simplified topic interface, we need to encode
(let [{:keys [event params type values]} t]
(cond
(some? event) (event-topic-enc event params);; event params topic {:event "Transfer" :params ["uint"]}
(some? type) (values-topic-enc type values) ;; indexed values topic
:else nil)) ;; error
:else nil))
(defn- ensure-hex-bn [block]
(cond
(nil? block) block
(re-matches #"^[0-9]+$" block) (str "0x" (abi-spec/number-to-hex block))
:else block))
(defn- execute-get-logs [_ {:keys [from to address topics block-hash] :as m}]
(let [params [{:fromBlock (ensure-hex-bn from)
:toBlock (ensure-hex-bn to)
:address address
:topics (generate-topic topics)
:blockhash block-hash}]]
(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
:extensions/ethereum-logs
(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-success on-failure]}]]
(if (ens/is-valid-eth-name? name)
(let [chain (ethereum/chain-keyword db)
registry (get ens/ens-registries chain)]
(ens/get-addr registry name
#(on-success {:value %})))
(when on-failure
(on-failure {:value (str "'" name "' is not a valid name")})))))
(handlers/register-handler-fx
:extensions/ethereum-sign
(fn [{db :db :as cofx} [_ _ {:keys [message data id on-success on-failure]}]]
(if (and message data)
(when on-failure
(on-failure {:error "only one of :message and :data can be used"}))
(signing/sign cofx {:message {:address (ethereum/current-address db)
:data (or data (ethereum/utf8-to-hex message))}
:on-result [:extensions/wallet-ui-on-success on-success]
:on-error [:extensions/wallet-ui-on-failure on-failure]}))))
(handlers/register-handler-fx
:extensions/ethereum-create-address
(fn [_ [_ _ {:keys [on-result]}]]
(let [args {:jsonrpc "2.0"
:method constants/status-create-address}
payload (types/clj->json args)]
(status/call-private-rpc payload #(let [{:keys [error result]} (types/json->clj %1)
response (if error {:result result :error error}
{:result result})]
(on-result response))))))
;; poll logs implementation
(handlers/register-handler-fx
:extensions/ethereum-logs-changes
(fn [_ [_ _ {:keys [id] :as 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
:extensions/ethereum-cancel-filter
(fn [_ [_ _ {:keys [id] :as m}]]
(rpc-call constants/web3-uninstall-filter [(abi-spec/number-to-hex id)] #(abi-spec/hex-to-value % "bool") m)))
(defn create-filter-method [type]
(case type
:filter constants/web3-new-filter
:block constants/web3-new-block-filter
:pending-transaction constants/web3-new-pending-transaction-filter))
(defn create-filter-arguments [type {:keys [from to address block-hash topics]}]
(case type
:filter
[{:fromBlock (ensure-hex-bn from)
:toBlock (ensure-hex-bn to)
:address address
:topics (mapv generate-topic topics)
:blockhash block-hash}]))
(handlers/register-handler-fx
:extensions/ethereum-create-filter
(fn [_ [_ _ {:keys [type] :as m}]]
(rpc-call (create-filter-method type) (create-filter-arguments type m) abi-spec/hex-to-number m)))
(handlers/register-handler-fx
:extensions/shh-post
(fn [_ [_ _ {:keys [from to topics payload priority ttl] :as m}]]
(let [params [{:from from
:to to
:topics (generate-topic topics)
:payload payload
:priority (abi-spec/number-to-hex priority)
:ttl (abi-spec/number-to-hex ttl)}]]
(rpc-call constants/web3-shh-post params #(abi-spec/hex-to-value % "bool") m))))
(handlers/register-handler-fx
:extensions/shh-new-identity
(fn [_ [_ _ arguments]]
(let [params []]
(rpc-call constants/web3-shh-new-identity params #(identity %) arguments))))
(handlers/register-handler-fx
:extensions/shh-has-identity
(fn [_ [_ _ {:keys [address] :as m}]]
((rpc-call constants/web3-shh-has-identity address #(abi-spec/hex-to-value % "bool") m))))
(handlers/register-handler-fx
:extensions/shh-new-group
(fn [_ [_ _ arguments]]
(let [params []]
(rpc-call constants/web3-shh-new-group params #(identity %) arguments))))
(handlers/register-handler-fx
:extensions/shh-add-to-group
(fn [_ [_ _ {:keys [address] :as m}]]
((rpc-call constants/web3-shh-add-to-group address #(abi-spec/hex-to-value % "bool") m))))
(handlers/register-handler-fx
:extensions/shh-new-filter
(fn [_ [_ _ {:keys [to topics] :as m}]]
(let [params [{:to to
:topics (generate-topic topics)}]]
(rpc-call constants/web3-shh-new-filter params abi-spec/hex-to-number m))))
(handlers/register-handler-fx
:extensions/shh-uninstall-filter
(fn [_ [_ _ {:keys [id] :as m}]]
(rpc-call constants/web3-shh-uninstall-filter [(abi-spec/number-to-hex id)] #(abi-spec/hex-to-value % "bool") m)))
(defn- parse-messages [{:keys [hash from to expiry ttl sent topics payload workProved]}]
{:hash hash
:from from
:to to
:expiry (abi-spec/hex-to-number expiry)
:ttl (abi-spec/hex-to-number ttl)
:sent (abi-spec/hex-to-number sent)
:topics topics
:payload payload
:workProved (abi-spec/hex-to-number workProved)})
(handlers/register-handler-fx
:extensions/shh-get-filter-changes
(fn [_ [_ _ {:keys [id] :as m}]]
(rpc-call constants/web3-shh-get-filter-changes [(abi-spec/number-to-hex id)] #(map parse-messages %) m)))
(handlers/register-handler-fx
:extensions/shh-get-messages
(fn [_ [_ _ {:keys [id] :as m}]]
(rpc-call constants/web3-shh-get-messages [(abi-spec/number-to-hex id)] #(map parse-messages %) m)))

View File

@ -1,747 +0,0 @@
(ns status-im.extensions.capacities.events
(:require [re-frame.core :as re-frame]
[status-im.utils.handlers :as handlers]
[clojure.string :as string]
[status-im.chat.commands.sending :as commands-sending]
[status-im.ui.screens.navigation :as navigation]
[status-im.ipfs.core :as ipfs]
[status-im.utils.fx :as fx]
[status-im.multiaccounts.update.core :as multiaccounts.update]
status-im.extensions.capacities.ethereum
status-im.extensions.capacities.camera.events
status-im.extensions.capacities.network))
(defn- empty-value? [o]
(cond
(seqable? o) (empty? o)
:else (nil? o)))
(defn- put-or-dissoc [db id key value]
(if (empty-value? value)
(update-in db [:extensions/store id] dissoc key)
(assoc-in db [:extensions/store id key] value)))
(defn- append [acc k v]
(let [o (get acc k)
ve (cond (vector? o) o
(not (nil? o)) (vector o)
:else [])]
(assoc acc k (conj ve v))))
(defn- json? [res]
(when-let [type (get-in res [:headers "content-type"])]
(string/starts-with? type "application/json")))
(defn- parse-json [o]
(when o
(js->clj (js/JSON.parse o) :keywordize-keys true)))
(defn- parse-result [o on-success]
(let [res (if (json? o) (update o :body parse-json) o)]
(on-success res)))
(defn operation->fn [k]
(case k
:plus +
:minus -
:times *
:divide /))
(defn update-multiaccount-data [{db :db :as cofx} id data-fn]
(let [{:keys [multiaccount]} db
extensions (get multiaccount :extensions)]
(multiaccounts.update/multiaccount-update
cofx
{:extensions (update-in extensions [id :data] data-fn)}
{})))
(defn- put-or-dissoc-persis [current-data key value]
(if value
(assoc current-data key value)
(dissoc current-data key)))
(fx/defn put-persistent
[cofx id {:keys [key value]}]
(update-multiaccount-data cofx id
(fn [current-data]
(put-or-dissoc-persis current-data key value))))
(fx/defn put-in-persistent
[cofx id {:keys [keys value]}]
(update-multiaccount-data cofx id
(fn [current-data]
(assoc-in current-data keys value))))
(fx/defn puts-persistent
[cofx id {:keys [value]}]
(update-multiaccount-data cofx id
(fn [current-data]
(reduce #(put-or-dissoc-persis %1 (:key %2) (:value %2)) current-data value))))
(fx/defn append-persistent
[cofx id {:keys [key value]}]
(update-multiaccount-data cofx id
(fn [current-data]
(append current-data key value))))
(fx/defn clear-persistent
[{db :db :as cofx} id {:keys [key]}]
(let [{:keys [multiaccount]} db
extensions (get multiaccount :extensions)]
(when (get-in extensions [id :data key])
(multiaccounts.update/multiaccount-update
cofx
{:extensions (update-in extensions [id :data] dissoc key)}
{}))))
(fx/defn clear-all-persistent
[{db :db :as cofx} id]
(let [{:keys [multiaccount]} db
extensions (get multiaccount :extensions)]
(when (get-in extensions [id :data])
(multiaccounts.update/multiaccount-update
cofx
{:extensions (update extensions id dissoc :data)}
{}))))
;;FX
(re-frame/reg-fx
::identity-event
(fn [{:keys [cb]}] (cb {})))
(re-frame/reg-fx
::alert
(fn [value] (js/alert value)))
(re-frame/reg-fx
::log
(fn [value] (js/console.log value)))
(re-frame/reg-fx
::schedule-start
(fn [{:keys [interval on-created on-result]}]
(let [id (js/setInterval #(on-result {}) interval)]
(on-created {:value id}))))
(re-frame/reg-fx
::schedule-cancel
(fn [{:keys [value]}]
(js/clearInterval value)))
(re-frame/reg-fx
::json-parse
(fn [{:keys [value on-result]}]
(on-result {:value (parse-json value)})))
(re-frame/reg-fx
::json-stringify
(fn [value on-result]
(on-result {:value (js/JSON.stringify (clj->js value))})))
(re-frame/reg-fx
::arithmetic
(fn [{:keys [operation values on-result]}]
(on-result {:value (apply (operation->fn operation) values)})))
;;EVENTS
(handlers/register-handler-fx
:extensions/identity-event
(fn [_ [_ _ m]]
{::identity-event m}))
(handlers/register-handler-fx
:alert
(fn [_ [_ _ {:keys [value]}]]
{::alert value}))
(handlers/register-handler-fx
:log
(fn [_ [_ _ {:keys [value]}]]
{::log value}))
(handlers/register-handler-fx
:extensions/schedule-start
(fn [_ [_ _ m]]
{::schedule-start m}))
(handlers/register-handler-fx
:extensions/schedule-cancel
(fn [_ [_ _ m]]
{::schedule-cancel m}))
(handlers/register-handler-fx
:store/put
(fn [{:keys [db] :as cofx} [_ {id :id} {:keys [key value persistent] :as arguments}]]
(fx/merge cofx
{:db (put-or-dissoc db id key value)}
(when persistent
(put-persistent id arguments)))))
(re-frame/reg-event-fx
:store/put-in
(fn [{:keys [db] :as cofx} [_ {id :id} {:keys [keys value persistent] :as arguments}]]
(fx/merge cofx
{:db (assoc-in db (into [] (concat [:extensions/store id] keys)) value)}
(when persistent
(put-in-persistent id arguments)))))
(handlers/register-handler-fx
:store/puts
(fn [{:keys [db] :as cofx} [_ {id :id} {:keys [value persistent] :as arguments}]]
(fx/merge cofx
{:db (reduce #(put-or-dissoc %1 id (:key %2) (:value %2)) db value)}
(when persistent
(puts-persistent id arguments)))))
(handlers/register-handler-fx
:store/append
(fn [{:keys [db] :as cofx} [_ {id :id} {:keys [key value persistent] :as arguments}]]
(fx/merge cofx
{:db (update-in db [:extensions/store id] append key value)}
(when persistent
(append-persistent id arguments)))))
(handlers/register-handler-fx
:store/clear
(fn [{:keys [db] :as cofx} [_ {id :id} {:keys [key]}]]
(fx/merge cofx
{:db (update-in db [:extensions/store id] dissoc key)}
(clear-persistent id key))))
(handlers/register-handler-fx
:store/clear-all
(fn [{:keys [db] :as cofx} [_ {id :id} _]]
(fx/merge cofx
{:db (update db :extensions/store dissoc id)}
(clear-all-persistent id))))
(handlers/register-handler-fx
:extensions/json-parse
(fn [_ [_ _ m]]
{::json-parse m}))
(handlers/register-handler-fx
:extensions/json-stringify
(fn [_ [_ _ {:keys [value]}]]
{::json-stringify value}))
(handlers/register-handler-fx
:http/get
(fn [_ [_ _ {:keys [url on-success on-failure timeout]}]]
{:http-raw-get (merge {:url url
:success-event-creator #(parse-result % on-success)}
(when on-failure
{:failure-event-creator on-failure})
(when timeout
{:timeout-ms timeout}))}))
(handlers/register-handler-fx
:ipfs/cat
(fn [cofx [_ _ args]]
(ipfs/cat cofx args)))
(handlers/register-handler-fx
:ipfs/add
(fn [cofx [_ _ args]]
(ipfs/add cofx args)))
(handlers/register-handler-fx
:http/post
(fn [_ [_ _ {:keys [url body on-success on-failure timeout]}]]
{:http-raw-post (merge {:url url
:body (clj->js body)
:success-event-creator #(parse-result % on-success)}
(when on-failure
{:failure-event-creator on-failure})
(when timeout
{:timeout-ms timeout}))}))
(handlers/register-handler-fx
:extensions.chat.command/set-parameter
(fn [_ [_ _ {:keys [value]}]]
{:dispatch [:chat.ui/set-command-parameter value]}))
(handlers/register-handler-fx
:extensions.chat.command/set-custom-parameter
(fn [{{:keys [current-chat-id] :as db} :db} [_ _ {:keys [key value]}]]
{:db (assoc-in db [:chats current-chat-id :custom-params key] value)}))
(handlers/register-handler-fx
:extensions.chat.command/set-parameter-with-custom-params
(fn [{{:keys [current-chat-id] :as db} :db} [_ _ {:keys [value params]}]]
{:db (update-in db [:chats current-chat-id :custom-params] merge params)
:dispatch [:chat.ui/set-command-parameter value]}))
(handlers/register-handler-fx
:extensions.chat.command/send-plain-text-message
(fn [_ [_ _ {:keys [value]}]]
{:dispatch [:chat/send-plain-text-message value]}))
(handlers/register-handler-fx
:extensions.chat.command/send-message
(fn [{{:keys [current-chat-id] :as db} :db :as cofx} [_ {:keys [hook-id]} {:keys [params]}]]
(when hook-id
(when-let [command (last (first (filter #(= (ffirst %) (name hook-id)) (:id->command db))))]
(commands-sending/send cofx current-chat-id command params)))))
(handlers/register-handler-fx
:extensions.chat.command/open-public-chat
(fn [_ [_ _ {:keys [topic navigate-to]}]]
{:dispatch [:chat.ui/start-public-chat topic {:dont-navigate? (not navigate-to) :navigation-reset? true}]}))
(handlers/register-handler-fx
:extensions/show-selection-screen
(fn [cofx [_ _ {:keys [on-select] :as params}]]
(navigation/navigate-to-cofx cofx
:selection-modal-screen
(assoc params :on-select #(do
(re-frame/dispatch [:navigate-back])
(on-select %))))))
(handlers/register-handler-fx
:extensions/arithmetic
(fn [_ [_ _ m]]
{::arithmetic m}))
(handlers/register-handler-fx
:extensions/profile-settings-close
(fn [{:keys [db] :as cofx} [_ _ {:keys [on-close on-failure]}]]
(let [view-id (:view-id db)]
;; ensure the current view-id is the profile settings view
(if (= view-id :my-profile-ext-settings)
(fx/merge cofx
(when on-close (on-close))
(navigation/navigate-back))
(if on-failure
(on-failure {:value "extension is not currently showing profile settings"})
{})))))
(handlers/register-handler-fx
:extensions/wallet-settings-close
(fn [{:keys [db] :as cofx} [_ _ {:keys [on-close on-failure]}]]
(let [view-id (:view-id db)]
;; ensure the current view-id is the wallet settings view
(if (= view-id :wallet-settings-hook)
(fx/merge cofx
(when on-close (on-close))
(navigation/navigate-back))
(if on-failure
(on-failure {:value "extension is not currently showing wallet settings"})
{})))))
(handlers/register-handler-fx
:extensions/screen-open
(fn [cofx [_ _ {:keys [view on-open]}]]
(fx/merge cofx
(when on-open (on-open))
(navigation/navigate-to-cofx :extension-screen-holder {:view view}))))
(handlers/register-handler-fx
:extensions/screen-close
(fn [{:keys [db] :as cofx} [_ _ {:keys [on-close on-failure]}]]
(let [view-id (:view-id db)]
;; ensure the current view-id is the extension fullscreen holder
(if (= view-id :extension-screen-holder)
(fx/merge cofx
(when on-close (on-close))
(navigation/navigate-back))
(if on-failure
(on-failure {:value "extension is not currently showing a fullscreen view"})
{})))))
;;CAPACITIES
(def all
{'identity
{:permissions [:read]
:data :extensions/identity-event
:arguments {:cb :event}}
'alert
{:permissions [:read]
:data :alert
:arguments {:value :string}}
'selection-screen
{:permissions [:read]
:data :extensions/show-selection-screen
:arguments {:items :vector :on-select :event :render :view :title :string :extractor-key :keyword}}
'chat.command/set-parameter
{:permissions [:read]
:data :extensions.chat.command/set-parameter
:arguments {:value :any}}
'chat.command/set-custom-parameter
{:permissions [:read]
:data :extensions.chat.command/set-custom-parameter
:arguments {:key :keyword :value :any}}
'chat.command/set-parameter-with-custom-params
{:permissions [:read]
:data :extensions.chat.command/set-parameter-with-custom-params
:arguments {:value :string :params :map}}
'chat.command/send-plain-text-message
{:permissions [:read]
:data :extensions.chat.command/send-plain-text-message
:arguments {:value :string}}
'chat.command/send-message
{:permissions [:read]
:data :extensions.chat.command/send-message
:arguments {:params :map}}
'chat.command/open-public-chat
{:permissions [:read]
:data :extensions.chat.command/open-public-chat
:arguments {:topic :string :navigate-to :boolean}}
'log
{:permissions [:read]
:data :log
:arguments {:value :string}}
'arithmetic
{:permissions [:read]
:data :extensions/arithmetic
:arguments {:values :vector
:operation {:one-of #{:plus :minus :times :divide}}
:on-result :event}}
'browser/open-url
{:permissions [:read]
:data :browser.ui/open-url
:arguments {:url :string}}
'camera/picture
{:permissions [:read]
:data :extensions/camera-picture
:arguments {:on-success :event
:on-failure? :event}}
'camera/qr-code
{:permissions [:read]
:data :extensions/camera-qr-code
:arguments {:on-success :event
:on-failure? :event}}
'schedule/start
{:permissions [:read]
:data :extensions/schedule-start
:arguments {:interval :number
:on-created :event
:on-result :event}}
'schedule/cancel
{:permissions [:read]
:data :extensions/schedule-cancel
:arguments {:value :number}}
'json/parse
{:permissions [:read]
:data :extensions/json-parse
:arguments {:value :string
:on-result :event}}
'json/stringify
{:permissions [:read]
:data :extensions/json-stringify
:arguments {:value :string
:on-result :event}}
'store/put
{:permissions [:read]
:data :store/put
:arguments {:key :string :value :any :persistent :boolean}}
'store/put-in
{:permissions [:read]
:data :store/put-in
:arguments {:keys :vector :value :any :persistent :boolean}}
'store/puts
{:permissions [:read]
:data :store/puts
:arguments {:value :vector :persistent :boolean}}
'store/append
{:permissions [:read]
:data :store/append
:arguments {:key :string :value :any :persistent :boolean}}
'store/clear
{:permissions [:read]
:data :store/clear
:arguments {:key :string}}
'store/clear-all
{:permissions [:read]
:data :store/clear-all}
'network/add
{:permissions [:read]
:data :network/add
:arguments {:chain-id :number
:name :string
:url :string
:on-success? :event
:on-failure? :event}}
'network/select
{:permissions [:read]
:data :network/select
:arguments {:chain-id :number
:on-success? :event
:on-failure? :event}}
'network/remove
{:permissions [:read]
:data :network/remove
:arguments {:chain-id :number
:on-success? :event
:on-failure? :event}}
'screen/open
{:permissions [:read]
:data :extensions/screen-open
:arguments {:view :view
:on-open? :event}}
'screen/close
{:permissions [:read]
:data :extensions/screen-close
:arguments {:on-close? :event
:on-failure? :event}}
'http/get
{:permissions [:read]
:data :http/get
:arguments {:url :string
:timeout? :string
:on-success :event
:on-failure? :event}}
'http/post
{:permissions [:read]
:data :http/post
:arguments {:url :string
:body :string
:timeout? :string
:on-success :event
:on-failure? :event}}
'ipfs/cat
{:permissions [:read]
:data :ipfs/cat
:arguments {:hash :string
:on-success :event
:on-failure? :event}}
'ipfs/add
{:permissions [:read]
:data :ipfs/add
:arguments {:value :string
:on-success :event
:on-failure? :event}}
'ethereum/transaction-receipt
{:permissions [:read]
:data :extensions/ethereum-transaction-receipt
:arguments {:value :string
:topics-hints :vector
:on-success :event
:on-failure? :event}}
'ethereum/await-transaction-receipt
{:permissions [:read]
:data :extensions/ethereum-await-transaction-receipt
:arguments {:value :string
:interval :number
:topics-hints :vector
:on-success :event
:on-failure? :event}}
'ethereum/sign
{:permissions [:read]
:data :extensions/ethereum-sign
:arguments {:message? :string
:data? :string
:on-success :event
:on-failure? :event}}
'ethereum/create-address
{:permissions [:read]
:data :extensions/ethereum-create-address
:arguments {:on-result :event}}
'ethereum/send-transaction
{:permissions [:read]
:data :extensions/ethereum-send-transaction
:arguments {:to :string
:gas? :string
:gas-price? :string
:value? :string
:method? :string
:params? :vector
:nonce? :string
:on-success? :event
:on-failure? :event}}
'ethereum/logs
{:permissions [:read]
:data :extensions/ethereum-logs
:arguments {:from? :string
:to? :string
:address? :vector
:topics? :vector
:block-hash? :string
:on-success :event
:on-failure? :event}}
'ethereum/create-filter
{:permissions [:read]
:data :extensions/ethereum-create-filter
:arguments {:type {:one-of #{:filter :block :pending-transaction}}
:from? :string
:to? :string
:address? :vector
:topics? :vector
:block-hash? :string
:on-success :event
:on-failure? :event}}
'ethereum/logs-changes
{:permissions [:read]
:data :extensions/ethereum-logs-changes
:arguments {:id :string
:topics-hints :vector}}
'ethereum/cancel-filter
{:permissions [:read]
:data :extensions/ethereum-cancel-filter
:arguments {:id :string}}
'ethereum.ens/resolve
{:permissions [:read]
:data :extensions/ethereum-resolve-ens
:arguments {:name :string
:on-success :event
:on-failure? :event}}
'ethereum.erc20/total-supply
{:permissions [:read]
:data :extensions/ethereum-erc20-total-supply
:arguments {:contract :string
:on-success :event
:on-failure? :event}}
'ethereum.erc20/balance-of
{:permissions [:read]
:data :extensions/ethereum-erc20-balance-of
:arguments {:contract :string
:token-owner :string
:on-success :event
:on-failure? :event}}
'ethereum.erc20/transfer
{:permissions [:read]
:data :extensions/ethereum-erc20-transfer
:arguments {:contract :string
:to :string
:value :number
:on-success :event
:on-failure? :event}}
'ethereum.erc20/transfer-from
{:permissions [:read]
:data :extensions/ethereum-erc20-transfer-from
:arguments {:contract :string
:from :string
:to :string
:value :number
:on-success :event
:on-failure? :event}}
'ethereum.erc20/approve
{:permissions [:read]
:data :extensions/ethereum-erc20-approve
:arguments {:contract :string
:spender :string
:value :number
:on-success :event
:on-failure? :event}}
'ethereum.erc20/allowance
{:permissions [:read]
:data :extensions/ethereum-erc20-allowance
:arguments {:contract :string
:token-owner :string
:spender :string
:on-success :event
:on-failure? :event}}
'ethereum.erc721/owner-of
{:permissions [:read]
:data :extensions/ethereum-erc721-owner-of
:arguments {:contract :string
:token-id :string
:on-success :event
:on-failure? :event}}
'ethereum.erc721/is-approved-for-all
{:permissions [:read]
:data :extensions/ethereum-erc721-is-approved-for-all
:arguments {:contract :string
:owner :string
:operator :string
:on-success :event
:on-failure? :event}}
'ethereum.erc721/get-approved
{:permissions [:read]
:data :extensions/ethereum-erc721-get-approved
:arguments {:contract :string
:token-id :string
:on-success :event
:on-failure? :event}}
'ethereum.erc721/set-approval-for-all
{:permissions [:read]
:data :extensions/ethereum-erc721-set-approval-for-all
:arguments {:contract :string
:operator :string
:approved :boolean
:on-success :event
:on-failure? :event}}
'ethereum.erc721/safe-transfer-from
{:permissions [:read]
:data :extensions/ethereum-erc721-safe-transfer-from
:arguments {:contract :string
:from :string
:to :string
:token-id :string
:data? :string
:on-success :event
:on-failure? :event}}
'ethereum/call
{:permissions [:read]
:data :extensions/ethereum-call
:arguments {:to :string
:method :string
:params? :vector
:outputs? :vector
:on-success :event
:on-failure? :event}}
'ethereum/shh_post
{:permissions [:read]
:data :extensions/shh-post
:arguments {:from? :string
:to? :string
:topics :vector
:payload :string
:priority :string
:ttl :string
:on-success :event
:on-failure? :event}}
'ethereum/shh-new-identity
{:permissions [:read]
:data :extensions/shh-new-identity
:arguments {:on-success :event
:on-failure? :event}}
'ethereum/shh-has-identity
{:permissions [:read]
:value :extensions/shh-has-identity
:arguments {:address :string
:on-success :event
:on-failure? :event}}
'ethereum/shh-new-group
{:permissions [:read]
:data :extensions/shh-new-group
:arguments {:on-success :event
:on-failure? :event}}
'ethereum/shh-add-to-group
{:permissions [:read]
:data :extensions/shh-add-to-group
:arguments {:address :string
:on-success :event
:on-failure? :event}}
'ethereum/shh_new-filter
{:permissions [:read]
:data :extensions/shh-new-filter
:arguments {:to? :string
:topics :vector
:on-success :event
:on-failure? :event}}
'ethereum/shh-uninstall-filter
{:permissions [:read]
:data :extensions/shh-uninstall-filter
:arguments {:id :string}}
'ethereum/shh-get-filter-changes
{:permissions [:read]
:data :extensions/shh-get-filter-changes
:arguments {:id :string}}
'ethereum/shh-get-messages
{:permissions [:read]
:data :extensions/shh-get-messages
:arguments {:id :string}}
'profile.settings/close
{:permissions [:read]
:data :extensions/profile-settings-close
:arguments {:on-close? :event
:on-failure? :event}}
'wallet.settings/close
{:permissions [:read]
:data :extensions/wallet-settings-close
:arguments {:on-close? :event
:on-failure? :event}}})

View File

@ -1,84 +0,0 @@
(ns status-im.extensions.capacities.map
(:require-macros
[status-im.utils.slurp :refer [slurp]]
[status-im.utils.views :refer [defview letsubs]])
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.utils.platform :as platform]
[status-im.utils.types :as types]
[status-im.ui.components.react :as react]
[status-im.ui.screens.browser.styles :as styles]
[status-im.react-native.js-dependencies :as js-dependencies]))
(def mapview-html (slurp "resources/mapview/mapview.html"))
(def webview-class
(memoize
(fn []
(reagent/adapt-react-class (.-WebView js-dependencies/webview)))))
(defn map-component
"creates a webview reagent component which cause webview to be updated only when style changes.
if injected-java-script changes, new javascript is run inside webview.
so, injected-java-script is not only used on webview initialization, but also to update webview state"
[opts wvref]
(reagent.core/create-class
{:should-component-update
(fn [_ [_ {:keys [style injected-java-script]}] [_ {new-injected-java-script :injected-java-script new-style :style}]]
(if (not= style new-style)
true
(do
(when (and @wvref (not= injected-java-script new-injected-java-script))
(.injectJavaScript @wvref new-injected-java-script))
false)))
:reagent-render
(fn [opts]
[(webview-class) opts])}))
(defn- on-map-message [map-event on-change]
(let [data (-> map-event
(.-nativeEvent)
(.-data)
(types/json->clj))]
(re-frame/dispatch (on-change {:value data}))))
(defn- web-view-error [_ code desc]
(reagent/as-element
[react/view styles/web-view-error
[react/i18n-text {:style styles/web-view-error-text :key :web-view-error}]
[react/text {:style styles/web-view-error-text}
(str code)]
[react/text {:style styles/web-view-error-text}
(str desc)]]))
(defview map-webview [{:keys [interactive fly style marker on-change]}]
(letsubs [webview (atom nil)]
[map-component
{:style style
:origin-whitelist ["*"]
:source {:html (mapview-html)
:base-url (cond
platform/ios? "./mapview/"
platform/android? "file:///android_asset/"
:else nil)}
:java-script-enabled true
:bounces false
:over-scroll-mode "never"
:local-storage-enabled true
:render-error web-view-error
;; load only local resources, for non-local resources open external browser
:on-should-start-load-with-request #(let [url (.-url %)]
(if (string/starts-with? url "file")
true
(do (.openURL (react/linking) url) false)))
:ref #(reset! webview %)
:on-message #(when on-change (on-map-message % on-change))
:injected-java-script (let [interactive? (boolean interactive) ;; force boolean
fly? (boolean fly)]
(if (map? marker)
(str "update(" (types/clj->json (assoc marker :fly fly? :interactive interactive?)) ");")
(str "init(" (types/clj->json {:interactive interactive?}) ");")))}
webview]))

View File

@ -1,41 +0,0 @@
(ns status-im.extensions.capacities.network
(:require [status-im.utils.handlers :as handlers]
[status-im.i18n :as i18n]
[status-im.network.module :as network]))
(handlers/register-handler-fx
:extensions/network-on-success
(fn [cofx [_ on-success result]]
(when on-success (on-success {:value result}))))
(defn- network-id [extension-id chain-id]
(str extension-id "_" chain-id))
(handlers/register-handler-fx
:network/select
(fn [cofx [_ _ {:keys [chain-id on-success on-failure]}]]
(if-let [network-id (network/get-network-id-for-chain-id cofx chain-id)]
(network/connect cofx {:network-id network-id
:on-success (when on-success #(on-success {:value %}))
:on-failure (when on-failure #(on-failure {:value %}))})
(when on-failure (on-failure {:value (i18n/label :t/extensions-network-not-found)})))))
(handlers/register-handler-fx
:network/add
(fn [{:keys [db] :as cofx} [_ {extension-id :id} {:keys [chain-id name url on-success on-failure]}]]
(network/save cofx {:data {:name {:value name}
:url {:value url}
:network-id {:value chain-id}
:chain {:value :custom}}
:network-id (network-id extension-id chain-id)
:success-event (when on-success [:extensions/network-on-success on-success chain-id])
:on-failure (when on-failure #(on-failure {:value %}))
:chain-id-unique? false})))
(handlers/register-handler-fx
:network/remove
(fn [cofx [_ {extension-id :id} {:keys [chain-id on-success on-failure]}]]
(let [network-id (network-id extension-id chain-id)]
(if (network/get-network cofx network-id)
(network/remove-network cofx network-id (when on-success [:extensions/network-on-success on-success chain-id]))
(when on-failure (on-failure {:value (i18n/label :t/extensions-chain-id-not-found)}))))))

View File

@ -1,13 +0,0 @@
(ns status-im.extensions.capacities.subs)
(def all
{'identity {:data :extensions/identity :arguments {:value :map}}
'store/get {:data :store/get :arguments {:key :string :reverse? :boolean}}
'store/get-in {:data :store/get-in :arguments {:key :vector}}
'store/get-vals {:data :store/get-vals :arguments {:key :string}}
'time/now {:data :extensions.time/now}
'contacts/all {:data :extensions.contacts/all} ;; :photo :name :address :public-key
'wallet/collectibles {:data :get-collectible-token :arguments {:token :string :symbol :string}}
'wallet/balance {:data :extensions.wallet/balance :arguments {:token :string}}
'wallet/token {:data :extensions.wallet/token :arguments {:token :string :amount? :number :amount-in-wei? :number}}
'wallet/tokens {:data :extensions.wallet/tokens :arguments {:filter? :vector :visible? :boolean}}})

View File

@ -1,13 +0,0 @@
(ns status-im.extensions.capacities.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.screens.profile.photo-capture.styles :as styles]))
(defview screen-holder []
(letsubs [{:keys [view]} [:get-screen-params]]
(when view
(let [[_ _ reactview] (view)]
[react/view styles/container
[status-bar/status-bar]
reactview]))))

View File

@ -1,4 +0,0 @@
(ns status-im.extensions.constants)
(def uri-prefix "https://get.status.im/extension/")
(def link-prefix "status-im://extension/")

View File

@ -1,92 +0,0 @@
(ns status-im.extensions.core
(:refer-clojure :exclude [list])
(:require [clojure.string :as string]
[pluto.core :as pluto]
[re-frame.core :as re-frame]
[re-frame.registrar :as registrar]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]
[status-im.extensions.capacities.components :as components]
[status-im.extensions.capacities.subs :as subs]
[status-im.extensions.capacities.events :as events]
[status-im.extensions.constants :as constants]))
(def capacities
{:components components/all
:queries subs/all
:events events/all
:hooks {:profile.settings
{:properties
{:label :string
:view :view
:on-open? :event
:on-close? :event}}
:wallet.settings
{:properties
{:label :string
:view :view
:on-open? :event
:on-close? :event}}
:chat.command
{:properties
{:description? :string
:scope #{:personal-chats :public-chats :group-chats}
:short-preview? :view
:preview? :view
:on-send? :event
:on-receive? :event
:on-send-sync? :event
:parameters? [{:id :keyword
:type {:one-of #{:text :phone :password :number}}
:placeholder :string
:suggestions? :view}]}}}})
(defn dispatch-events [_ events]
(doseq [event events]
(when (vector? event)
(re-frame/dispatch event))))
(defn resolve-query [[id :as data]]
(when (registrar/get-handler :sub id)
(re-frame/subscribe data)))
(defn parse [{:keys [data]} id]
(try
(pluto/parse {:capacities capacities
:env {:id id}
:event-fn dispatch-events
:query-fn resolve-query}
data)
(catch :default e {:errors [{:value (str e)}]})))
(defn parse-extension [{:keys [type value]} id]
(if (= type :success)
(parse (pluto/read (:content value)) id)
{:errors [{:type type :value value}]}))
(defn valid-uri? [s]
(boolean
(when s
(let [s' (string/trim s)]
(or
(re-matches (re-pattern (str "^" constants/uri-prefix "\\w+@.+")) s')
(re-matches (re-pattern (str "^" constants/link-prefix "\\w+@.+")) s'))))))
(fx/defn set-extension-url-from-qr
[cofx url]
(fx/merge (assoc-in cofx [:db :extensions/manage :url] {:value url
:error false})
(navigation/navigate-back)))
(fx/defn set-input
[{:keys [db]} input-key value]
{:db (update db :extensions/manage assoc input-key {:value value})})
(fx/defn fetch [cofx ext-key]
(get-in cofx [:db :multiaccount :extensions ext-key]))
(fx/defn edit
[cofx extension-key]
(let [{:keys [url]} (fetch cofx extension-key)]
(fx/merge (set-input cofx :url (str url))
(navigation/navigate-to-cofx :edit-extension nil))))

View File

@ -1,44 +0,0 @@
(ns status-im.extensions.events
(:require [status-im.utils.handlers :as handlers]
[status-im.extensions.core :as extensions]
[status-im.extensions.registry :as extensions.registry]))
(handlers/register-handler-fx
:extensions.callback/qr-code-scanned
(fn [cofx [_ _ url]]
(extensions/set-extension-url-from-qr cofx url)))
(handlers/register-handler-fx
:extensions.ui/add-extension-pressed
(fn [cofx [_ extension-key]]
(extensions/edit cofx extension-key)))
(handlers/register-handler-fx
:extensions.ui/uninstall-extension-pressed
(fn [cofx [_ extension-key]]
(extensions.registry/uninstall cofx extension-key)))
(handlers/register-handler-fx
:extensions.ui/input-changed
(fn [cofx [_ input-key value]]
(extensions/set-input cofx input-key value)))
(handlers/register-handler-fx
:extensions.ui/activation-checkbox-pressed
(fn [cofx [_ extension-key active?]]
(extensions.registry/change-state cofx extension-key active?)))
(handlers/register-handler-fx
:extensions.ui/find-button-pressed
(fn [cofx [_ url]]
(extensions.registry/load cofx url false)))
(handlers/register-handler-fx
:extensions.ui/install-extension-button-pressed
(fn [cofx [_ url]]
(extensions.registry/install-from-message cofx url true)))
(handlers/register-handler-fx
:extensions.ui/install-button-pressed
(fn [cofx [_ url data modal?]]
(extensions.registry/install cofx url data modal?)))

View File

@ -1,78 +0,0 @@
(ns status-im.extensions.module
(:require-macros [status-im.modules :as modules])
(:require status-im.extensions.ui.db
[pluto.storages :as storages]
[re-frame.core :as re-frame]
[status-im.utils.fx :as fx]
[clojure.string :as string]
[status-im.extensions.constants :as constants]))
(modules/defmodule extensions
{:load 'status-im.extensions.registry/load
:valid-uri? 'status-im.extensions.core/valid-uri?
:parse-extension 'status-im.extensions.core/parse-extension
:take-picture-view 'status-im.extensions.capacities.camera.views/take-picture
:screen-holder-view 'status-im.extensions.capacities.views/screen-holder
:extensions-settings-view 'status-im.extensions.ui.views/extensions-settings
:selection-modal-screen-view 'status-im.extensions.ui.views/selection-modal-screen
:edit-extension-view 'status-im.extensions.ui.add.views/edit-extension
:show-extension-view 'status-im.extensions.ui.add.views/show-extension
:show-extension-modal-view 'status-im.extensions.ui.add.views/show-extension-modal})
(defn load [& args]
(apply (get-symbol :load) args))
(defn valid-uri? [& args]
(apply (get-symbol :valid-uri?) args))
(defn parse-extension [& args]
(apply (get-symbol :parse-extension) args))
(defn take-picture-view []
[(get-symbol :take-picture-view)])
(defn screen-holder-view []
[(get-symbol :screen-holder-view)])
(defn extensions-settings-view []
[(get-symbol :extensions-settings-view)])
(defn selection-modal-screen-view []
[(get-symbol :selection-modal-screen-view)])
(defn edit-extension-view []
[(get-symbol :edit-extension-view)])
(defn show-extension-view []
[(get-symbol :show-extension-view)])
(defn show-extension-modal-view []
[(get-symbol :show-extension-modal-view)])
;; Initialization
;; Prevents loading of the rest of the module till it is necessary.
(defn url->uri [s]
(when s
(-> s
(string/replace constants/uri-prefix "")
(string/replace constants/link-prefix ""))))
(defn load-from [url f]
(when-let [uri (url->uri url)]
(storages/fetch uri f)))
(re-frame/reg-fx
:extensions/load
(fn [{:keys [extensions follow-up]}]
(doseq [{:keys [url active?]} extensions]
(load-from url #(re-frame/dispatch [follow-up url (parse-extension % url) active?])))))
(fx/defn initialize
[{{:keys [multiaccount] :as db} :db}]
(let [{:keys [extensions dev-mode?]} multiaccount
ext-vals (vals extensions)]
(when dev-mode?
{:db (assoc db :extensions/store (into {} (map (fn [{:keys [id data]}] {id data}) ext-vals)))
:extensions/load {:extensions ext-vals
:follow-up :extensions/add-to-registry}})))

View File

@ -1,221 +0,0 @@
(ns status-im.extensions.registry
(:refer-clojure :exclude [list])
(:require [clojure.set :as set]
[clojure.string :as string]
[re-frame.core :as re-frame]
[pluto.core :as pluto]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.chat.commands.core :as commands]
[status-im.chat.commands.protocol :as protocol]
[status-im.i18n :as i18n]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]))
(defprotocol Hook
"Encapsulate hook lifecycle."
(hook-in [this id env properties cofx] "Hook it into host app.")
(unhook [this id env properties cofx] "Remove extension hook from app."))
(defmulti hook-for (fn [hook] (pluto/hook-type hook)))
(defmethod hook-for "wallet.settings" [_]
(reify Hook
(hook-in [_ id _ m {:keys [db]}]
(fn [{:keys [db]}] {:db (assoc-in db [:wallet :settings id] m)}))
(unhook [_ id _ _ {:keys [db]}]
(fn [{:keys [db]}] {:db (update-in db [:wallet :settings] dissoc id)}))))
(defmethod hook-for "profile.settings" [_]
(reify Hook
(hook-in [_ id _ m {:keys [db]}]
(fn [{:keys [db]}] {:db (assoc-in db [:extensions/profile :settings id] m)}))
(unhook [_ id _ _ {:keys [db]}]
(fn [{:keys [db]}] {:db (update-in db [:extensions/profile :settings] dissoc id)}))))
(defmethod hook-for "chat.command" [_]
(reify Hook
(hook-in [_ id {extension-id :id} {:keys [description scope parameters preview short-preview
on-send on-receive on-send-sync]} cofx]
(let [new-command (if on-send-sync
(reify protocol/Command
(id [_] (name id))
(scope [_] scope)
(description [_] description)
(parameters [_] (or parameters []))
(validate [_ _ _])
(on-send [_ command-message _] (when on-send (on-send command-message)))
(on-receive [_ command-message _] (when on-receive (on-receive command-message)))
(short-preview [_ props] (when short-preview (short-preview props)))
(preview [_ props] (when preview (preview props)))
protocol/Yielding
(yield-control [_ props _] (on-send-sync props))
protocol/Extension
(extension-id [_] extension-id))
(reify protocol/Command
(id [_] (name id))
(scope [_] scope)
(description [_] description)
(parameters [_] (or parameters []))
(validate [_ _ _])
(on-send [_ command-message _] (when on-send (on-send command-message)))
(on-receive [_ command-message _] (when on-receive (on-receive command-message)))
(short-preview [_ props] (when short-preview (short-preview props)))
(preview [_ props] (when preview (preview props)))
protocol/Extension
(extension-id [_] extension-id)))]
(fn [cofx]
(commands/load-commands cofx [new-command]))))
(unhook [_ id _ {:keys [scope]} {:keys [db] :as cofx}]
(when-let [command (get-in db [:id->command [(name id) scope] :type])]
(commands/remove-command command cofx)))))
(defmethod hook-for :default [a]
(reify Hook
(hook-in [this id env properties cofx])
(unhook [this id env properties cofx])))
(defn hook-id
[s]
(when s
(last (string/split (name s) #"\."))))
(fx/defn update-hooks
[{:keys [db] :as cofx} hook-fn extension-id]
(let [multiaccount (get db :multiaccount)
hooks (get-in multiaccount [:extensions extension-id :hooks])]
(apply fx/merge cofx
(map (fn [[type extension]]
(hook-fn (hook-for type) (hook-id type) {:id extension-id} extension cofx))
hooks))))
(fx/defn disable-hooks
[{:keys [db] :as cofx} extension-id]
(update-hooks cofx unhook extension-id))
(fx/defn add-to-registry
[{:keys [db] :as cofx} extension-id extension-data active?]
(let [{:keys [hooks]} extension-data
on-init (get-in extension-data [:lifecycle :on-init])]
(fx/merge cofx
{:db (update-in db [:multiaccount :extensions extension-id] merge {:hooks hooks :active? active?})}
(update-hooks hook-in extension-id)
(when on-init (on-init)))))
(fx/defn remove-from-registry
[cofx extension-id]
(let [extensions (get-in cofx [:db :multiaccount :extensions])]
(fx/merge cofx
(when (get-in extensions [extension-id :active?])
(update-hooks unhook extension-id))
{:db (update-in cofx [:db :multiaccount :extensions] dissoc extension-id)})))
(fx/defn change-state
[cofx extension-key active?]
(let [extensions (get-in cofx [:db :multiaccount :extensions])
new-extensions (assoc-in extensions [extension-key :active?] active?)
hook-fn (if active?
hook-in
unhook)
lifecycle-event (if active?
(get-in extensions [extension-key :lifecycle :on-activation])
(get-in extensions [extension-key :lifecycle :on-deactivation]))]
(fx/merge cofx
;; on-deactivate called before
(when (and (not active?) lifecycle-event) (lifecycle-event))
(multiaccounts.update/multiaccount-update {:extensions new-extensions} {:success-event nil})
(update-hooks hook-fn extension-key)
;; on-activation called after
(when (and active? lifecycle-event) (lifecycle-event)))))
(fx/defn install
[{:keys [db] :as cofx} url {:keys [hooks] :as extension-data} modal?]
(let [{:keys [multiaccount]} db
on-installation (get-in extension-data [:lifecycle :on-installation])
on-activation (get-in extension-data [:lifecycle :on-activation])
ephemeral? (get-in extension-data [:lifecycle :ephemeral])
extension {:id url
:name (or (get-in extension-data [:meta :name]) "Unnamed")
:url url
:lifecycle {:on-installation on-installation
:on-deinstallation (get-in extension-data [:lifecycle :on-deinstallation])
:on-activation on-activation
:on-deactivation (get-in extension-data [:lifecycle :on-deactivation])
:ephemeral? ephemeral?}
:active? true}
new-extensions (assoc (:extensions multiaccount) url extension)]
(fx/merge cofx
#(if modal?
(navigation/navigate-back %)
(navigation/navigate-to-cofx % :my-profile nil))
#(when-not ephemeral?
(fx/merge %
(when hooks (multiaccounts.update/multiaccount-update {:extensions new-extensions} {}))
(when hooks (add-to-registry url extension-data true))
(when on-installation (on-installation))))
(when on-activation (on-activation)))))
(fx/defn uninstall
[{:keys [db] :as cofx} extension-key]
(let [{:keys [multiaccount]} db
extension (get-in cofx [:db :multiaccount :extensions extension-key])
active? (get extension :active?)
on-deinstallation (get-in extension [:lifecycle :on-deinstallation])
on-deactivation (get-in extension [:lifecycle :on-deactivation])
new-extensions (dissoc (:extensions multiaccount) extension-key)]
(fx/merge cofx
(when (and active? on-deactivation) (on-deactivation))
(when on-deinstallation (on-deinstallation))
(remove-from-registry extension-key)
(multiaccounts.update/multiaccount-update {:extensions new-extensions} {}))))
(fx/defn load
[cofx url modal?]
(if (get-in cofx [:db :multiaccount :extensions url])
{:utils/show-popup {:title (i18n/label :t/error)
:content (i18n/label :t/extension-is-already-added)}}
{:extensions/load {:extensions [{:url (string/trim url)
:active? true}]
:follow-up (if modal? :extensions/stage-modal :extensions/stage)}}))
(fx/defn install-from-message
[cofx url modal?]
(if (get-in cofx [:db :multiaccount :dev-mode?])
(load cofx url modal?)
{:ui/show-confirmation
{:title (i18n/label :t/confirm-install)
:content (i18n/label :t/extension-install-alert)
:on-accept #(do
(re-frame/dispatch [:multiaccounts.ui/dev-mode-switched true])
(re-frame/dispatch [:extensions.ui/install-extension-button-pressed url]))}}))
(defn existing-hooks-for
[type cofx extension-data]
(let [added-hooks (reduce (fn [acc [_ {:keys [hooks]}]]
(->> (type hooks)
(keys)
(into acc)))
#{}
(get-in cofx [:db :multiaccount :extensions]))
hooks (->> (get-in extension-data [:hooks type])
(keys)
(into #{}))]
(set/intersection added-hooks hooks)))
(defn existing-hooks [cofx extension-data]
(->> (get-in extension-data [:hooks])
(keys)
(map #(existing-hooks-for % cofx extension-data))
(apply set/union)))
(fx/defn stage-extension [{:keys [db] :as cofx} url extension-data modal?]
(let [hooks (existing-hooks cofx extension-data)]
(if (empty? hooks)
(fx/merge cofx
{:db (assoc db :extensions/staged-extension {:url url
:extension-data extension-data})}
(navigation/navigate-to-cofx (if modal? :show-extension-modal :show-extension) nil))
{:utils/show-popup {:title (i18n/label :t/error)
:content (i18n/label :t/extension-hooks-cannot-be-added
{:hooks (->> hooks
(map name)
(clojure.string/join ", "))})}})))

View File

@ -1,26 +0,0 @@
(ns status-im.extensions.ui.add.events
(:require [status-im.extensions.registry :as extensions.registry]
[status-im.utils.handlers :as handlers]
[status-im.utils.fx :as fx]))
(handlers/register-handler-fx
:extensions/stage
(fn [cofx [_ url extension-data]]
(extensions.registry/stage-extension cofx url extension-data false)))
(handlers/register-handler-fx
:extensions/stage-modal
(fn [cofx [_ url extension-data]]
(extensions.registry/stage-extension cofx url extension-data true)))
(handlers/register-handler-fx
:extensions/add-to-registry
(fn [cofx [_ extension-key {:keys [data]} active?]]
(extensions.registry/add-to-registry cofx extension-key data active?)))
(handlers/register-handler-fx
:extensions/disable-all-hooks
(fn [cofx [_ extensions]]
(apply fx/merge cofx (map (fn [{:keys [id]}]
(extensions.registry/disable-hooks cofx id))
extensions))))

View File

@ -1,53 +0,0 @@
(ns status-im.extensions.ui.add.styles
(:require-macros [status-im.utils.styles :refer [defstyle]])
(:require [status-im.ui.components.styles :as styles]
[status-im.ui.components.colors :as colors]))
(def screen
{:flex 1
:background-color colors/white})
(def wrapper
{:flex 1
:margin 16})
(def input-container
{:flex-direction :row
:align-items :center
:justify-content :space-between
:border-radius styles/border-radius
:height 52
:margin-top 15})
(defstyle input
{:flex 1
:android {:padding 0}})
(def bottom-container
{:flex-direction :row
:margin-horizontal 12
:margin-vertical 15})
(def hooks
{:margin-top 20
:margin-left 10})
(def cartouche-container
{:flex 1
:margin-top 16
:margin-horizontal 16})
(def cartouche-header
{:color colors/gray})
(def cartouche-content-wrapper
{:flex-direction :row
:margin-top 8
:border-color colors/gray-lighter
:border-width 1
:border-radius styles/border-radius
:padding 16
:background-color colors/white-transparent})
(def qr-code
{:margin-right 14})

View File

@ -1,111 +0,0 @@
(ns status-im.extensions.ui.add.views
(:require-macros [status-im.utils.views :as views])
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[clojure.string :as string]
[pluto.error :as error]
[status-im.extensions.core :as core]
[status-im.i18n :as i18n]
[status-im.ui.components.react :as react]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.text-input.view :as text-input]
[status-im.extensions.ui.add.styles :as styles]
status-im.extensions.ui.add.events))
(defn cartouche [{:keys [header]} content]
[react/view {:style styles/cartouche-container}
[react/text {:style styles/cartouche-header}
header]
[react/view {:style styles/cartouche-content-wrapper}
[react/view {:flex 1}
content]]])
(views/defview show-extension-base [modal?]
(views/letsubs [{:keys [extension-data url]} [:get-staged-extension]]
(let [{:keys [data errors]} extension-data]
(if data
[react/view styles/screen
[status-bar/status-bar]
[react/keyboard-avoiding-view components.styles/flex
[toolbar/simple-toolbar (i18n/label :t/extension) modal?]
[react/scroll-view {:keyboard-should-persist-taps :handled}
[react/view styles/wrapper
[react/view {:style {:border-radius 8 :margin 10 :padding 8 :background-color colors/red}}
[react/text {:style {:color colors/white}}
(i18n/label :t/extensions-disclaimer)]]
[cartouche {:header (i18n/label :t/identifier)}
[react/text (str (get-in data [:meta :name]))]]
[cartouche {:header (i18n/label :t/name)}
[react/text (str (get-in data [:meta :name]))]]
[cartouche {:header (i18n/label :t/description)}
[react/text (str (get-in data [:meta :description]))]]
[cartouche {:header (i18n/label :t/hooks)}
(into [react/view] (for [hook (keys (:hooks data))]
[react/text (str hook)]))]
[cartouche {:header (i18n/label :t/permissions)}
[react/text (i18n/label :t/none)]]
[cartouche {:header (i18n/label :t/errors)}
(if errors
(into [react/view] (for [{::error/keys [type target]} errors]
[react/text
(str (when type (name type)) " " (when target (name target)))]))
[react/text (i18n/label :t/none)])]]]
[react/view styles/bottom-container
[react/view components.styles/flex]
[components.common/bottom-button
{:forward? true
:label (i18n/label :t/install)
:disabled? (not (empty? errors))
:on-press #(re-frame/dispatch [:extensions.ui/install-button-pressed url data modal?])}]]]]
[react/view styles/screen
[status-bar/status-bar]
[react/view {:flex 1}
[toolbar/simple-toolbar (i18n/label :t/extension)]
[react/view {:style {:flex 1 :justify-content :center :align-items :center}}
[react/text (i18n/label :t/invalid-extension)]
[react/text (str errors)]]]]))))
(views/defview show-extension []
[show-extension-base false])
(views/defview show-extension-modal []
[show-extension-base true])
(def qr-code
[react/touchable-highlight {:on-press #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
{:toolbar-title (i18n/label :t/scan-qr)}
:extensions.callback/qr-code-scanned])
:style styles/qr-code}
[react/view
[vector-icons/icon :main-icons/qr {:color colors/blue}]]])
(views/defview edit-extension []
(views/letsubs [manage-extension [:get-manage-extension]]
(let [url (get-in manage-extension [:url :value])
pressed (reagent/atom false)]
[react/view styles/screen
[status-bar/status-bar]
[react/keyboard-avoiding-view components.styles/flex
[toolbar/simple-toolbar (i18n/label :t/extension-find)]
[react/scroll-view {:keyboard-should-persist-taps :handled}
[react/view styles/wrapper
[text-input/text-input-with-label
{:label (i18n/label :t/extension-address)
:style styles/input
:container styles/input-container
:content qr-code
:default-value url
:placeholder (i18n/label :t/extension-url)
:on-change-text #(re-frame/dispatch [:extensions.ui/input-changed :url %])}]]]
[react/view styles/bottom-container
[react/view components.styles/flex]
[components.common/bottom-button
{:forward? true
:label (i18n/label :t/find)
:disabled? (and (not @pressed) (not (core/valid-uri? url)))
:on-press #(do (reset! pressed true) (re-frame/dispatch [:extensions.ui/find-button-pressed (string/trim url)]))}]]]])))

View File

@ -1,20 +0,0 @@
(ns status-im.extensions.ui.db
(:require
[clojure.string :as string]
[cljs.spec.alpha :as spec]))
(spec/def ::not-blank-string (complement string/blank?))
(spec/def :extension/id ::not-blank-string)
(spec/def :extension/name ::not-blank-string)
(spec/def :extension/url ::not-blank-string)
(spec/def :extension/active? boolean?)
(spec/def :extension/data (spec/nilable map?))
(spec/def :extension/extension (spec/keys :req-un [:extension/id
:extension/name
:extension/url
:extension/active?]
:opt-un [:extension/data
:extension/hooks]))
(spec/def :extensions/extensions (spec/nilable (spec/map-of :extension/id :extension/extension)))

View File

@ -1,20 +0,0 @@
(ns status-im.extensions.ui.styles
(:require [status-im.ui.components.colors :as colors])
(:require-macros [status-im.utils.styles :refer [defstyle]]))
(def wrapper
{:flex 1
:background-color colors/white})
(defn mailserver-icon [connected?]
{:width 40
:height 40
:border-radius 20
:background-color (if connected?
colors/blue
colors/black-transparent)
:align-items :center
:justify-content :center})
(def empty-list
{:text-align :center})

View File

@ -1,72 +0,0 @@
(ns status-im.extensions.ui.views
(:require-macros [status-im.utils.views :as views])
(:require [re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.toolbar.actions :as toolbar.actions]
[status-im.extensions.ui.styles :as styles]
status-im.extensions.events))
(def mailserver-icon
[react/view (styles/mailserver-icon true)
[vector-icons/icon :main-icons/mailserver {:color :white}]])
(defn- render-extension [{:keys [name url active?]}]
[list/deletable-list-item {:type :extensions
:id url
:on-delete #(do
(re-frame/dispatch [:set-swipe-position :extensions url false])
(re-frame/dispatch [:extensions.ui/uninstall-extension-pressed url]))}
[list/list-item-with-checkbox
{:checked? active?
:on-value-change #(re-frame/dispatch [:extensions.ui/activation-checkbox-pressed url %])}
[list/item
mailserver-icon
[list/item-content
[list/item-primary name]
[list/item-secondary url]]]]])
(views/defview extensions-settings []
(views/letsubs [extensions [:extensions/all-extensions]]
[react/view {:flex 1}
[status-bar/status-bar]
[toolbar/toolbar {}
toolbar/default-nav-back
[toolbar/content-title (i18n/label :t/extensions)]
[toolbar/actions
[(toolbar.actions/add false #(re-frame/dispatch [:extensions.ui/add-extension-pressed]))]]]
[react/view styles/wrapper
[list/flat-list {:data (vals extensions)
:default-separator? false
:key-fn :id
:render-fn render-extension
:content-container-style (merge (when (zero? (count extensions))
{:flex-grow 1})
{:justify-content :center})
:empty-component [react/text {:style styles/empty-list}
(i18n/label :t/no-extension)]}]]]))
(defn- render-selection-item [render on-select]
(fn [item]
[react/touchable-highlight {:on-press #(on-select item)}
[render item]]))
(views/defview selection-modal-screen []
(views/letsubs [{:keys [items render title extractor-key on-select]} [:get-screen-params :selection-modal-screen]]
[react/view {:flex 1}
[status-bar/status-bar]
[toolbar/toolbar {}
toolbar/default-nav-close
[toolbar/content-title title]]
[react/view styles/wrapper
[list/flat-list {:data items
:default-separator? false
:key-fn extractor-key
:render-fn (render-selection-item render on-select)
:content-container-style {:justify-content :center}
:empty-component [react/text {:style styles/empty-list}
"No items"]}]]]))

View File

@ -1,81 +0,0 @@
(ns status-im.models.dev-server
(:require [clojure.string :as string]
[status-im.browser.core :as browser]
[status-im.network.module :as network]
[status-im.utils.fx :as fx]))
(defn start
[]
{:dev-server/start nil})
;; Specific server operations
(defmulti process-request! (fn [{:keys [url type]}] [type (first url) (second url)]))
(defmethod process-request! [:POST "ping" nil]
[{:keys [request-id]}]
{:dev-server/respond [request-id 200 {:message "Pong!"}]})
(defmethod process-request! [:POST "dapp" "open"]
[{{:keys [request-id url]} :data cofx :cofx}]
(fx/merge cofx
{:dev-server/respond [request-id 200 {:message "URL has been opened."}]}
(browser/open-url url)))
(defmethod process-request! [:POST "network" nil]
[{:keys [cofx request-id data]}]
(let [data (->> data
(map (fn [[k v]] [k {:value v}]))
(into {}))]
(network/save
cofx
{:data data
:on-success (fn [network _]
{:dev-server/respond
[request-id 200 {:message "Network has been added."
:network-id network}]})
:on-failure (fn [_ _]
{:dev-server/respond
[request-id 400 {:message "Please, check the validity of network information."}]})})))
(defmethod process-request! [:POST "network" "connect"]
[{:keys [cofx request-id data]}]
(network/connect
cofx
{:network-id (:id data)
:on-success (fn [{:keys [network-id client-version]} _]
{:dev-server/respond
[request-id 200 {:message "Network has been connected."
:network-id network-id
:client-version client-version}]})
:on-failure (fn [{:keys [network-id reason]} _]
{:dev-server/respond
[request-id 400 {:message "Cannot connect the network."
:network-id network-id
:reason reason}]})}))
(defmethod process-request! [:GET "networks" nil]
[{:keys [cofx request-id]}]
(let [{:keys [networks network]} (get-in cofx [:db :multiaccount])
networks (->> networks
(map (fn [[id m]]
[id (-> m
(select-keys [:id :name :config])
(assoc :active? (= id network)))]))
(into {}))]
{:dev-server/respond [request-id 200 {:networks networks}]}))
(defmethod process-request! [:DELETE "network" nil]
[{:keys [cofx request-id data]}]
(network/delete
cofx
{:network (:id data)
:on-success (fn [network _]
{:dev-server/respond [request-id 200 {:message "Network has been deleted."
:network-id network}]})
:on-failure (fn [_ _]
{:dev-server/respond [request-id 400 {:message "Cannot delete the provided network."}]})}))
(defmethod process-request! :default
[{:keys [request-id type url]}]
{:dev-server/respond [request-id 404 {:message (str "Not found (" (name type) " " (string/join "/" url) ")")}]})

View File

@ -51,27 +51,11 @@
(multiaccounts.update/multiaccount-update cofx
{:wallet-set-up-passed? true} {}))
(fx/defn update-dev-server-state
[_ dev-mode?]
(if dev-mode?
{:dev-server/start nil}
{:dev-server/stop nil}))
(fx/defn update-extensions-state
[{{:keys [multiaccount]} :db} dev-mode?]
(let [extensions (-> multiaccount :extensions vals)]
(if dev-mode?
{:extensions/load {:extensions extensions
:follow-up :extensions/add-to-registry}}
{:dispatch [:extensions/disable-all-hooks extensions]})))
(fx/defn switch-dev-mode
[cofx dev-mode?]
(fx/merge cofx
(update-dev-server-state dev-mode?)
(update-extensions-state dev-mode?)
(multiaccounts.update/multiaccount-update {:dev-mode? dev-mode?}
{})))
(multiaccounts.update/multiaccount-update cofx
{:dev-mode? dev-mode?}
{}))
(fx/defn switch-chaos-mode
[{:keys [db] :as cofx} chaos-mode?]

View File

@ -2,7 +2,6 @@
(:require status-im.utils.db
status-im.network.module
status-im.ui.screens.bootnodes-settings.db
status-im.extensions.module
[cljs.spec.alpha :as spec]
[status-im.constants :as const]))
@ -28,7 +27,6 @@
(spec/def :multiaccount/network (spec/nilable string?))
(spec/def :multiaccount/networks (spec/nilable :networks/networks))
(spec/def :multiaccount/bootnodes (spec/nilable :bootnodes/bootnodes))
(spec/def :multiaccount/extensions (spec/nilable :extensions/extensions))
(spec/def :multiaccount/mailserver (spec/nilable string?))
(spec/def :multiaccount/settings (spec/nilable (spec/map-of keyword? any?)))
(spec/def :multiaccount/signing-phrase :global/not-empty-string)
@ -53,11 +51,11 @@
:multiaccount/debug? :multiaccount/last-updated :multiaccount/public-key
:multiaccount/email :multiaccount/signed-up? :multiaccount/network
:multiaccount/networks :multiaccount/settings :multiaccount/mailserver
:multiaccount/last-sign-in :multiaccount/sharing-usage-data? :multiaccount/dev-mode?
:multiaccount/sharing-usage-data?
:multiaccount/seed-backed-up? :multiaccount/mnemonic :multiaccount/desktop-notifications?
:multiaccount/chaos-mode?
:multiaccount/wallet-set-up-passed? :multiaccount/last-request
:multiaccount/bootnodes :multiaccount/extensions
:multiaccount/bootnodes
:multiaccount/mainnet-warning-shown-version
:multiaccount/desktop-alpha-release-warning-shown?
:multiaccount/keycard-instance-uid

View File

@ -9,7 +9,6 @@
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ethereum.transactions.core :as transactions]
[status-im.extensions.module :as extensions.module]
[status-im.fleet.core :as fleet]
[status-im.i18n :as i18n]
[status-im.native-module.core :as status]

View File

@ -13,7 +13,6 @@
[{:keys [db] :as cofx}]
(fx/merge cofx
{::logout nil
:dev-server/stop nil
;;TODO sort out this mess with lower case addresses
:keychain/clear-user-password (string/lower-case (get-in db [:multiaccount :address]))
::init/open-multiaccounts #(re-frame/dispatch [::init/initialize-multiaccounts %])}

View File

@ -75,8 +75,6 @@
(reg-root-key-sub :tab-bar-visible? :tab-bar-visible?)
(reg-root-key-sub :dimensions/window :dimensions/window)
(reg-root-key-sub :initial-props :initial-props)
(reg-root-key-sub :get-manage-extension :extensions/manage)
(reg-root-key-sub :get-staged-extension :extensions/staged-extension)
(reg-root-key-sub :get-device-UUID :device-UUID)
(reg-root-key-sub :fleets/custom-fleets :custom-fleets)
(reg-root-key-sub :chain-sync-state :node/chain-sync-state)
@ -104,7 +102,6 @@
(reg-root-key-sub :my-profile/seed :my-profile/seed)
(reg-root-key-sub :my-profile/advanced? :my-profile/advanced?)
(reg-root-key-sub :my-profile/editing? :my-profile/editing?)
(reg-root-key-sub :extensions/profile :extensions/profile)
(reg-root-key-sub :my-profile/profile :my-profile/profile)
;;multiaccount
(reg-root-key-sub :multiaccounts/multiaccounts :multiaccounts/multiaccounts)
@ -898,16 +895,6 @@
(fn [[{:keys [:stickers/recent-stickers]} packs]]
(map (fn [hash] {:hash hash :pack (find-pack-id-for-hash hash packs)}) recent-stickers)))
;;EXTENSIONS ===========================================================================================================
(re-frame/reg-sub
:extensions/all-extensions
:<- [:multiaccount]
(fn [multiaccount]
(get multiaccount :extensions)))
;;HOME =================================================================================================================
(re-frame/reg-sub
:home-items
:<- [:chats/active-chats]
@ -1585,91 +1572,6 @@
{}
contacts)))
;;EXTENSIONS ============================================================================================================
;;TODO not optimized yet
(re-frame/reg-sub
:extensions/identity
(fn [_ [_ _ {:keys [value]}]]
value))
(defn get-token-for [chain all-tokens token]
(if (= token "ETH")
{:decimals 18
:address "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}
(tokens/token-for chain all-tokens token)))
(re-frame/reg-sub
:extensions.wallet/balance
:<- [:wallet/all-tokens]
:<- [:ethereum/chain-keyword]
:<- [:balance]
(fn [[all-tokens chain balance] [_ _ {token :token}]]
(let [{:keys [decimals]} (get-token-for chain all-tokens token)
value (or (get balance (keyword token)) (money/bignumber 0))]
{:value (money/token->unit value decimals)
:value-in-wei value})))
(re-frame/reg-sub
:extensions.wallet/token
:<- [:wallet/all-tokens]
:<- [:network]
(fn [[all-tokens network] [_ _ {token :token amount :amount amount-in-wei :amount-in-wei}]]
(let [{:keys [decimals] :as m} (get-token-for network all-tokens token)]
(merge m
(when amount {:amount-in-wei (money/unit->token amount decimals)})
(when amount-in-wei {:amount (money/token->unit amount-in-wei decimals)})))))
(defn normalize-token [m]
(update m :symbol name))
(re-frame/reg-sub
:extensions.wallet/tokens
:<- [:wallet/all-tokens]
:<- [:wallet/visible-tokens-symbols]
:<- [:ethereum/chain-keyword]
(fn [[all-tokens visible-tokens-symbols chain] [_ _ {filter-vector :filter visible :visible}]]
(let [tokens (map normalize-token (filter #(and (not (:nft? %)) (if visible (contains? visible-tokens-symbols (:symbol %)) true))
(tokens/sorted-tokens-for all-tokens chain)))]
(if filter-vector
(filter #((set filter-vector) (:symbol %)) tokens)
tokens))))
(re-frame/reg-sub
:store/get
(fn [db [_ {id :id} {:keys [key] :as params}]]
(let [result (get-in db [:extensions/store id key])]
(if (:reverse params)
(reverse result)
result))))
(re-frame/reg-sub
:store/get-in
(fn [db [_ {id :id} {:keys [keys]}]]
(get-in db (into [] (concat [:extensions/store id] keys)))))
(defn- ->contact [{:keys [photo-path address name public-key]}]
{:photo photo-path
:name name
:address (str "0x" address)
:public-key public-key})
(re-frame/reg-sub
:extensions.contacts/all
:<- [:contacts/active]
(fn [[contacts] _]
(map #(update % :address ->contact))))
(re-frame/reg-sub
:store/get-vals
(fn [db [_ {id :id} {:keys [key]}]]
(vals (get-in db [:extensions/store id key]))))
(re-frame/reg-sub
:extensions.time/now
(fn [_ _]
(.toLocaleString (js/Date.))))
;;MAILSERVER ===========================================================================================================
(re-frame/reg-sub

View File

@ -52,7 +52,6 @@
:log-level-settings {:type :main}
:stickers-pack-modal {:type :main}
:tribute-learn-more {:type :main}
:show-extension-modal {:type :main}
:wallet {:type :main}
:wallet-stack {:type :main}
:recipient-qr-code {:type :transparent}

View File

@ -4,7 +4,6 @@
[status-im.chat.commands.protocol :as protocol]
[status-im.chat.commands.receiving :as commands-receiving]
[status-im.constants :as constants]
[status-im.extensions.module :as extensions.module]
[status-im.i18n :as i18n]
[status-im.ui.components.action-sheet :as action-sheet]
[status-im.ui.components.colors :as colors]
@ -20,34 +19,13 @@
[status-im.utils.config :as config])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn install-extension-message [extension-id outgoing]
[react/touchable-highlight {:on-press #(re-frame/dispatch
[:extensions.ui/install-extension-button-pressed extension-id])}
[react/view style/extension-container
[vector-icons/icon :main-icons/info {:color (if outgoing colors/white colors/gray)}]
[react/text {:style (style/extension-text outgoing)}
(i18n/label :to-see-this-message)]
[react/text {:style (style/extension-install outgoing)}
(i18n/label :install-the-extension)]]])
(defview message-content-command
[command-message]
(letsubs [id->command [:chats/id->command]
{:keys [contacts]} [:chats/current-chat]]
(let [{:keys [type] :as command} (commands-receiving/lookup-command-by-ref command-message id->command)
extension-id (get-in command-message [:content :params :extension-id])]
(let [{:keys [type] :as command} (commands-receiving/lookup-command-by-ref command-message id->command)]
;;TODO temporary disable commands for v1
[react/text (str "Unhandled command: " (-> command-message :content :command-path first))]
#_(if (and config/extensions-enabled? platform/mobile? extension-id
(extensions.module/valid-uri? extension-id)
(or (not type) (and type (satisfies? protocol/Extension type)
(not= extension-id (protocol/extension-id type)))))
;; Show install message only for mobile and if message contains extension id and there is no extension installed
;; or installed extension has differen extension id
[install-extension-message extension-id (:outgoing command-message)]
(if command
(commands/generate-preview command (commands/add-chat-contacts contacts command-message))
[react/text (str "Unhandled command: " (-> command-message :content :command-path first))])))))
[react/text (str "Unhandled command: " (-> command-message :content :command-path first))])))
(defview message-timestamp
[t justify-timestamp? outgoing command? content content-type]

View File

@ -210,16 +210,3 @@
:color (if outgoing
colors/white-transparent-70
colors/gray)})
(def extension-container
{:align-items :center
:margin 10})
(defn extension-text [outgoing]
{:font-size 12
:margin-top 10
:color (if outgoing colors/white-transparent colors/gray)})
(defn extension-install [outgoing]
{:font-size 12
:color (if outgoing colors/white colors/blue)})

View File

@ -133,7 +133,6 @@
(spec/def :navigation.screen-params/collectibles-list map?)
(spec/def :navigation.screen-params/show-extension map?)
(spec/def :navigation.screen-params/selection-modal-screen map?)
(spec/def :navigation.screen-params/manage-dapps-permissions map?)
@ -144,7 +143,6 @@
:navigation.screen-params/group-contacts
:navigation.screen-params/edit-contact-group
:navigation.screen-params/collectibles-list
:navigation.screen-params/show-extension
:navigation.screen-params/selection-modal-screen
:navigation.screen-params/manage-dapps-permissions])))
@ -164,11 +162,6 @@
(spec/def ::collectible (spec/nilable map?))
(spec/def ::collectibles (spec/nilable map?))
(spec/def ::extension-url (spec/nilable string?))
(spec/def :extensions/staged-extension (spec/nilable any?))
(spec/def :extensions/manage (spec/nilable any?))
(spec/def ::extensions-store (spec/nilable any?))
;;;;NODE
(spec/def ::message-envelopes (spec/nilable map?))
@ -201,7 +194,6 @@
(spec/def :stickers/packs-installed (spec/nilable map?))
(spec/def :stickers/selected-pack (spec/nilable any?))
(spec/def :stickers/recent (spec/nilable vector?))
(spec/def :extensions/profile (spec/nilable any?))
(spec/def :wallet/custom-token-screen (spec/nilable map?))
(spec/def :signing/in-progress? (spec/nilable boolean?))
@ -238,8 +230,6 @@
:networks/networks
:networks/manage
:bootnodes/manage
:extensions/staged-extension
:extensions/manage
:node/status
:node/chain-sync-state
:universal-links/url
@ -282,7 +272,6 @@
:bottom-sheet/show?
:bottom-sheet/view
:bottom-sheet/options
:extensions/profile
:wallet/custom-token-screen
:signing/in-progress?
:signing/queue
@ -352,7 +341,6 @@
::supported-biometric-auth
::collectible
::collectibles
::extensions-store
:registry/registry
::two-pane-ui-enabled?
::generate-account]))

View File

@ -1,6 +1,5 @@
(ns status-im.ui.screens.events
(:require status-im.events
status-im.dev-server.events
status-im.ui.screens.add-new.events
status-im.ui.screens.add-new.new-chat.events
status-im.ui.screens.group.chat-settings.events

View File

@ -69,10 +69,8 @@
(defn- my-profile-settings [{:keys [seed-backed-up? mnemonic]}
{:keys [settings]}
logged-in?
extensions]
(let [show-backup-seed? (and (not seed-backed-up?) (not (string/blank? mnemonic)))
extensions-settings (vals (get extensions :settings))]
logged-in?]
(let [show-backup-seed? (and (not seed-backed-up?) (not (string/blank? mnemonic)))]
[react/view
[profile.components/settings-title (i18n/label :t/settings)]
(when (and config/hardwallet-enabled?
@ -110,13 +108,6 @@
{:label-kw :t/dapps-permissions
:accessibility-label :dapps-permissions-button
:action-fn #(re-frame/dispatch [:navigate-to :dapps-permissions])}]
(when extensions-settings
(for [{:keys [label] :as st} extensions-settings]
[react/view
[profile.components/settings-item-separator]
[profile.components/settings-item
{:item-text label
:action-fn #(re-frame/dispatch [:navigate-to :my-profile-ext-settings st])}]]))
[profile.components/settings-item-separator]
[profile.components/settings-item
{:label-kw :t/need-help
@ -141,11 +132,6 @@
[{:keys [network :networks/networks chaos-mode? dev-mode? settings]} on-show supported-biometric-auth]
{:component-did-mount on-show}
[react/view
(when (and config/extensions-enabled? dev-mode?)
[profile.components/settings-item
{:label-kw :t/extensions
:action-fn #(re-frame/dispatch [:navigate-to :extensions-settings])
:accessibility-label :extensions-button}])
(when dev-mode?
[profile.components/settings-item
{:label-kw :t/network
@ -270,14 +256,6 @@
[:tribute-to-talk.ui/menu-item-pressed])}
opts)])
(defview extensions-settings []
(letsubs [{:keys [label view on-close]} [:get-screen-params :my-profile-ext-settings]]
[react/keyboard-avoiding-view {:style {:flex 1}}
[status-bar/status-bar {:type :main}]
[toolbar/simple-toolbar label]
[react/scroll-view
[view]]]))
(defn- header [{:keys [public-key photo-path] :as account}]
[profile.components/profile-header
{:contact account
@ -309,7 +287,6 @@
(letsubs [list-ref (reagent/atom nil)
{:keys [public-key photo-path preferred-name]
:as current-multiaccount} [:multiaccount]
extensions [:extensions/profile]
changed-multiaccount [:my-profile/profile]
currency [:wallet/currency]
login-data [:multiaccounts/login]
@ -333,7 +310,7 @@
[contacts-list-item active-contacts-count]
(when tribute-to-talk [tribute-to-talk-item tribute-to-talk])
[my-profile-settings current-multiaccount shown-multiaccount
currency (nil? login-data) extensions]
currency (nil? login-data)]
(when (nil? login-data) [advanced shown-multiaccount on-show-advanced])]]
[(react/safe-area-view) {:style {:flex 1}}
[status-bar/status-bar {:type :main}]

View File

@ -10,7 +10,6 @@
:new-chat
:qr-scanner
:take-picture
:extension-screen-holder
:new-group
:add-participants-toggle-list
:contact-toggle-list

View File

@ -2,7 +2,6 @@
(def modal-screens
[:chat-modal
:show-extension-modal
:stickers-pack-modal
:tribute-learn-more
:enter-pin-modal

View File

@ -20,10 +20,6 @@
:help-center
:dapps-permissions
:manage-dapps-permissions
:extensions-settings
:extension-screen-holder
:edit-extension
:show-extension
:network-settings
:network-details
:edit-network

View File

@ -1,6 +1,5 @@
(ns status-im.ui.screens.routing.screens
(:require [status-im.extensions.module :as extensions.module]
[status-im.ui.screens.about-app.views :as about-app]
(:require [status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.screens.multiaccounts.login.views :as login]
[status-im.ui.screens.multiaccounts.recover.views :as multiaccounts.recover]
[status-im.ui.screens.multiaccounts.views :as multiaccounts]
@ -121,8 +120,6 @@
:new add-new/add-new
:new-chat new-chat/new-chat
:qr-scanner qr-scanner/qr-scanner
:take-picture extensions.module/take-picture-view
:extension-screen-holder extensions.module/screen-holder-view
:new-group group/new-group
:add-participants-toggle-list group/add-participants-toggle-list
:contact-toggle-list group/contact-toggle-list
@ -135,7 +132,6 @@
:stickers-pack-modal [:modal stickers/pack-modal]
:tribute-learn-more [:modal tr-to-talk/learn-more]
:chat-modal [:modal chat/chat-modal]
:show-extension-modal [:modal extensions.module/show-extension-modal-view]
:wallet wallet.accounts/accounts-overview
:wallet-account wallet.account/account
:collectibles-list collectibles/collectibles-list
@ -149,13 +145,11 @@
:wallet-request-assets wallet.components/request-assets
:wallet-transaction-details wallet-transactions/transaction-details
:wallet-settings-hook wallet-settings/settings-hook
:selection-modal-screen [:modal extensions.module/selection-modal-screen-view]
:wallet-settings-assets wallet-settings/manage-assets
:wallet-add-custom-token custom-tokens/add-custom-token
:wallet-custom-token-details custom-tokens/custom-token-details
:wallet-transactions-filter [:modal wallet-transactions/filter-history]
:my-profile profile.user/my-profile
:my-profile-ext-settings profile.user/extensions-settings
:contacts-list contacts-list/contacts-list
:ens-main ens/main
:ens-register ens/register
@ -172,9 +166,6 @@
:help-center help-center/help-center
:dapps-permissions dapps-permissions/dapps-permissions
:manage-dapps-permissions dapps-permissions/manage
:extensions-settings extensions.module/extensions-settings-view
:edit-extension extensions.module/edit-extension-view
:show-extension extensions.module/show-extension-view
:network-settings network/network-settings-view
:network-details network/network-details-view
:edit-network network/edit-network-view

View File

@ -24,7 +24,6 @@
:recent-recipients]}
:wallet-transaction-details
:wallet-settings-hook
:extension-screen-holder
:wallet-settings-assets
:wallet-add-custom-token
:wallet-custom-token-details

View File

@ -26,7 +26,6 @@
(def pairing-popup-disabled? (enabled? (get-config :PAIRING_POPUP_DISABLED "0")))
(def cached-webviews-enabled? (enabled? (get-config :CACHED_WEBVIEWS_ENABLED 0)))
(def snoopy-enabled? (enabled? (get-config :SNOOPY 0)))
(def extensions-enabled? (enabled? (get-config :EXTENSIONS 0)))
(def hardwallet-enabled? (enabled? (get-config :HARDWALLET_ENABLED 0)))
(def dev-build? (enabled? (get-config :DEV_BUILD 0)))
(def erc20-contract-warnings-enabled? (enabled? (get-config :ERC20_CONTRACT_WARNINGS)))

View File

@ -6,7 +6,6 @@
[status-im.chat.models :as chat]
[status-im.constants :as constants]
[status-im.ethereum.eip681 :as eip681]
[status-im.extensions.module :as extensions.module]
[status-im.pairing.core :as pairing]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.react :as react]
@ -24,7 +23,6 @@
(def public-chat-regex #".*/chat/public/(.*)$")
(def profile-regex #".*/user/(.*)$")
(def browse-regex #".*/browse/(.*)$")
(def extension-regex #".*/extension/(.*)$")
;; domains should be without the trailing slash
(def domains {:external "https://get.status.im"
@ -79,10 +77,6 @@
(desktop.events/show-profile-desktop public-key cofx)
(navigation/navigate-to-cofx (assoc-in cofx [:db :contacts/identity] public-key) :profile nil))))
(fx/defn handle-extension [cofx url]
(log/info "universal-links: handling url profile" url)
(extensions.module/load cofx url false))
(fx/defn handle-eip681 [cofx url]
{:dispatch-n [[:navigate-to :wallet-send-transaction]
[:wallet/fill-request-from-url url :deep-link]]})
@ -110,9 +104,6 @@
(match-url url browse-regex)
(handle-browse cofx (match-url url browse-regex))
(and config/extensions-enabled? (match-url url extension-regex))
(handle-extension cofx url)
(some? (eip681/parse-uri url))
(handle-eip681 cofx url)

View File

@ -1,10 +0,0 @@
(ns status-im.test.extensions.core
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.extensions.core :as extensions]))
(deftest valid-uri?
(is (= false (extensions/valid-uri? nil)))
(is (= false (extensions/valid-uri? "http://get.status.im/extension/ipfs")))
(is (= false (extensions/valid-uri? " http://get.status.im/extension/ipfs@QmWKqSanV4M4zrd55QMkvDMZEQyuHzCMHpX1Fs3dZeSExv ")))
(is (= true (extensions/valid-uri? " https://get.status.im/extension/ipfs@QmWKqSanV4M4zrd55QMkvDMZEQyuHzCMHpX1Fs3dZeSExv ")))
(is (= true (extensions/valid-uri? "https://get.status.im/extension/ipfs@QmWKqSanV4M4zrd55QMkvDMZEQyuHzCMHpX1Fs3dZeSExv"))))

View File

@ -1,50 +0,0 @@
(ns status-im.test.extensions.ethereum
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.extensions.capacities.ethereum :as ethereum]))
; ethereum/logs
(deftest test-parse-topic-events
(testing "topic parsing check - events"
(is (= ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
"0x29f31b934498b0deabbe211b01cc30eee6475abf0f0d553e7eb8ca71deeb24b3"]
(ethereum/generate-topic [{:event "Transfer" :params ["address" "address" "uint256"]}
{:event "drawBet" :params ["uint256" "uint8" "int8" "address" "uint256"]}])))))
(deftest test-parse-topic-indexed-values-address
(testing "topic parsing check - indexed values address"
(is (= ["0x000000000000000000000000299b18709d4aacbda99048721448f65893a0c73a"
"0x00000000000000000000000094eaa5fa6b313968b2abd6da375ef28077d95d53"]
(ethereum/generate-topic {:type "address" :values ["0x299b18709d4aacbda99048721448f65893a0c73a" "0x94eaa5fa6b313968b2abd6da375ef28077d95d53"]})))))
(deftest test-parse-topic-indexed-values-uint256
(testing "topic parsing check - indexed values uint256"
(is (= ["0x00000000000000000000000000000000000000000000000000000000000003fd"
"0x0000000000000000000000000000000000000000000000000000000000000078"]
(ethereum/generate-topic {:type "uint256" :values ["0x3fd" "120"]})))))
(deftest test-parse-topic-indexed-values-direct
(testing "topic parsing check - indexed values direct"
(is (= ["0x00000000000000000000000000000000000000000000000000000000000003fd"
"0x0000000000000000000000000000000000000000000000000000000000000078"]
(ethereum/generate-topic ["0x00000000000000000000000000000000000000000000000000000000000003fd"
"0x0000000000000000000000000000000000000000000000000000000000000078"])))))
(deftest test-parse-topic-indexed-nil
(testing "topic parsing check - nil"
(is (= ["0x00000000000000000000000000000000000000000000000000000000000003fd"
nil]
(ethereum/generate-topic ["0x00000000000000000000000000000000000000000000000000000000000003fd"
nil])))))
(deftest test-ensure-hex-bn-nonnumber
(is (= "latest" (ethereum/ensure-hex-bn "latest"))))
(deftest test-ensure-hex-bn-int
(is (= "0xa" (ethereum/ensure-hex-bn "10"))))
(deftest test-ensure-hex-bn-hex
(is (= "0xf" (ethereum/ensure-hex-bn "0xf"))))
(deftest test-ensure-hex-bn-nil
(is (= nil (ethereum/ensure-hex-bn nil))))

View File

@ -26,9 +26,7 @@
[status-im.test.ethereum.eip681]
[status-im.test.ethereum.ens]
[status-im.test.ethereum.mnemonic]
[status-im.test.extensions.core]
[status-im.test.ethereum.stateofus]
[status-im.test.extensions.ethereum]
[status-im.test.fleet.core]
[status-im.test.group-chats.core]
[status-im.test.hardwallet.core]
@ -113,8 +111,6 @@
'status-im.test.ethereum.ens
'status-im.test.ethereum.mnemonic
'status-im.test.ethereum.stateofus
'status-im.test.extensions.core
'status-im.test.extensions.ethereum
'status-im.test.fleet.core
'status-im.test.group-chats.core
'status-im.test.hardwallet.core

View File

@ -143,10 +143,7 @@
:URL "https://poa.infura.io"}}
:rpc-url nil}}
:photo-path "data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX////YsYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPGFwxAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEAAAAAAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQAAAAABAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAloYA4a9rBHIAAAAASUVORK5CYII="
:debug? false
:extensions {}
:mainnet-warning-shown? false
:last-sign-in 1547271706793
:seed-backed-up? false
:network "mainnet_rpc"
:wallet-set-up-passed? false