remove dev-server and extensions for v1
This commit is contained in:
parent
d7cd2b8a74
commit
d61fffb021
1
deps.edn
1
deps.edn
|
@ -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"}}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
67
project.clj
67
project.clj
|
@ -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]}}}}})
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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]))
|
|
@ -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))))
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)))
|
|
@ -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)}]}))))
|
|
@ -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
|
||||
|
|
|
@ -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}})))
|
|
@ -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])})
|
|
@ -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}}})
|
|
@ -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)))
|
|
@ -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}}})
|
|
@ -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]))
|
|
@ -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)}))))))
|
|
@ -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}}})
|
|
@ -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]))))
|
|
@ -1,4 +0,0 @@
|
|||
(ns status-im.extensions.constants)
|
||||
|
||||
(def uri-prefix "https://get.status.im/extension/")
|
||||
(def link-prefix "status-im://extension/")
|
|
@ -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))))
|
|
@ -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?)))
|
|
@ -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}})))
|
|
@ -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 ", "))})}})))
|
|
@ -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))))
|
|
@ -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})
|
|
@ -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)]))}]]]])))
|
|
@ -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)))
|
|
@ -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})
|
|
@ -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"]}]]]))
|
|
@ -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) ")")}]})
|
|
@ -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?]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 %])}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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)})
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}]
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
:new-chat
|
||||
:qr-scanner
|
||||
:take-picture
|
||||
:extension-screen-holder
|
||||
:new-group
|
||||
:add-participants-toggle-list
|
||||
:contact-toggle-list
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
(def modal-screens
|
||||
[:chat-modal
|
||||
:show-extension-modal
|
||||
:stickers-pack-modal
|
||||
:tribute-learn-more
|
||||
:enter-pin-modal
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"))))
|
|
@ -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))))
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue