118 lines
5.2 KiB
Plaintext
Raw Normal View History

(ns status-im.models.network
(:require [re-frame.core :as re-frame]
[clojure.string :as string]
[status-im.i18n :as i18n]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.ui.screens.accounts.utils :as accounts.utils]))
(def url-regex
#"https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}(\.[a-z]{2,6})?\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)")
(defn valid-rpc-url? [url]
(boolean (re-matches url-regex (str url))))
(def default-manage
{:name {:value ""}
:url {:value ""}
:chain {:value :mainnet}})
(defn validate-string [{:keys [value]}]
{:value value
:error (string/blank? value)})
(defn validate-url [{:keys [value]}]
{:value value
:error (not (valid-rpc-url? value))})
(defn validate-manage [manage]
(-> manage
(update :url validate-url)
(update :name validate-string)
(update :chain validate-string)))
(defn valid-manage? [manage]
(->> (validate-manage manage)
vals
(map :error)
(not-any? identity)))
(defn new-network [random-id network-name upstream-url type network-id]
(let [data-dir (str "/ethereum/" (name type) "_rpc")
config {:NetworkId (or (when network-id (int network-id))
(ethereum/chain-keyword->chain-id type))
:DataDir data-dir
:UpstreamConfig {:Enabled true
:URL upstream-url}}]
{:id (string/replace random-id "-" "")
:name network-name
:config config}))
(defn get-chain [{:keys [db]}]
(let [network (get (:networks (:account/account db)) (:network db))]
(ethereum/network->chain-keyword network)))
(defn set-input [input-key value {:keys [db]}]
{:db (-> db
(update-in [:networks/manage input-key] assoc :value value)
(update-in [:networks/manage] validate-manage))})
(defn- action-handler
([handler]
(handler nil nil))
([handler data cofx]
(when handler
(handler data cofx))))
(defn save
([cofx]
(save cofx nil))
([{{:network/keys [manage]
:account/keys [account] :as db} :db :as cofx}
{:keys [data on-success on-failure]}]
(let [data (or data manage)]
(if (valid-manage? data)
(let [{:keys [name url chain network-id]} data
network (new-network (:random-id cofx) (:value name) (:value url) (:value chain) (:value network-id))
new-networks (merge {(:id network) network} (:networks account))]
(handlers-macro/merge-fx cofx
{:db (dissoc db :networks/manage)}
(action-handler on-success (:id network))
(accounts.utils/account-update {:networks new-networks})))
(action-handler on-failure)))))
;; No edit functionality actually implemented
(defn edit [{db :db}]
{:db (assoc db :networks/manage (validate-manage default-manage))
:dispatch [:navigate-to :edit-network]})
(defn connect [{:keys [db now] :as cofx} {:keys [network on-success on-failure]}]
(if (get-in db [:account/account :networks network])
(let [current-network (get-in db [:account/account :networks (:network db)])]
(if (ethereum/network-with-upstream-rpc? current-network)
(handlers-macro/merge-fx cofx
(action-handler on-success network)
(accounts.utils/account-update {:network network
:last-updated now}
[:logout]))
(handlers-macro/merge-fx {:show-confirmation {:title (i18n/label :t/close-app-title)
:content (i18n/label :t/close-app-content)
:confirm-button-text (i18n/label :t/close-app-button)
:on-accept #(re-frame/dispatch [::save-network network])
:on-cancel nil}}
(action-handler on-success network))))
(action-handler on-failure)))
(defn delete [{{:account/keys [account]} :db} {:keys [network on-success on-failure]}]
(let [current-network? (= (:network account) network)]
(if (or current-network?
(not (get-in account [:networks network])))
(handlers-macro/merge-fx {:show-error (i18n/label :t/delete-network-error)}
(action-handler on-failure network))
(handlers-macro/merge-fx {:show-confirmation {:title (i18n/label :t/delete-network-title)
:content (i18n/label :t/delete-network-confirmation)
:confirm-button-text (i18n/label :t/delete)
:on-accept #(re-frame/dispatch [::remove-network network])
:on-cancel nil}}
(action-handler on-success network)))))