Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a99526cae4 | ||
|
|
312683ec3b | ||
|
|
95e8cf44b2 | ||
|
|
fc18880178 | ||
|
|
285c7c40ea | ||
|
|
5437a984a8 | ||
|
|
a9e13f5aff | ||
|
|
cdf5fe292f | ||
|
|
70f0ba7784 | ||
|
|
f03671097b | ||
|
|
1db63a9fa1 | ||
|
|
cd92b41214 | ||
|
|
56f7206da7 | ||
|
|
eb5de3506a | ||
|
|
22005f916e | ||
|
|
ff50aacb3a | ||
|
|
91300b9ff8 | ||
|
|
d93b20242a | ||
|
|
0a43e5c97a |
@@ -0,0 +1,2 @@
|
||||
{:lint-as {malli.experimental/defn schema.core/defn}
|
||||
:linters {:unresolved-symbol {:exclude [(malli.core/=>)]}}}
|
||||
@@ -0,0 +1,4 @@
|
||||
{:linters
|
||||
{:unresolved-symbol
|
||||
{:exclude [(cljs.test/is [match? thrown-match?])
|
||||
(clojure.test/is [match? thrown-match?])]}}}
|
||||
@@ -77,7 +77,6 @@ pipeline {
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
when { expression { !utils.isReleaseBuild() } }
|
||||
steps { script {
|
||||
env.DIAWI_URL = ios.uploadToDiawi()
|
||||
env.PKG_URL = env.DIAWI_URL
|
||||
|
||||
+5
@@ -1183,6 +1183,11 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
return pathCombine(absRootDirPath, "keystore");
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String fleets() {
|
||||
return Statusgo.fleets();
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String backupDisabledDataDir() {
|
||||
return this.getNoBackupDirectory();
|
||||
|
||||
@@ -981,6 +981,10 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isAddress:(NSString *)address) {
|
||||
return StatusgoIsAddress(address);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(fleets) {
|
||||
return StatusgoFleets();
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(toChecksumAddress:(NSString *)address) {
|
||||
return StatusgoToChecksumAddress(address);
|
||||
}
|
||||
|
||||
@@ -298,6 +298,7 @@ void _MultiAccountStoreAccount(const FunctionCallbackInfo<Value>& args) {
|
||||
delete c;
|
||||
}
|
||||
|
||||
|
||||
void _InitKeystore(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
@@ -562,6 +563,17 @@ void _CheckAddressChecksum(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
}
|
||||
|
||||
void _Fleets(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = Fleets();
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
}
|
||||
|
||||
|
||||
void _IsAddress(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
@@ -1888,6 +1900,7 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreDerivedAccounts", _MultiAccountStoreDerivedAccounts);
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreAccount", _MultiAccountStoreAccount);
|
||||
NODE_SET_METHOD(exports, "initKeystore", _InitKeystore);
|
||||
NODE_SET_METHOD(exports, "fleets", _Fleets);
|
||||
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
|
||||
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
|
||||
NODE_SET_METHOD(exports, "encodeFunctionCall", _EncodeFunctionCall);
|
||||
|
||||
@@ -40,23 +40,6 @@
|
||||
config
|
||||
#(callback (types/json->clj %))))
|
||||
|
||||
(defn save-account-and-login
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[key-uid multiaccount-data hashed-password settings config accounts-data]
|
||||
(log/debug "[native-module] save-account-and-login"
|
||||
"multiaccount-data"
|
||||
multiaccount-data)
|
||||
(clear-web-data)
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.saveAccountAndLogin
|
||||
^js (status)
|
||||
multiaccount-data
|
||||
hashed-password
|
||||
settings
|
||||
config
|
||||
accounts-data)))
|
||||
|
||||
(defn save-multiaccount-and-login-with-keycard
|
||||
"NOTE: chat-key is a whisper private key sent from keycard"
|
||||
[key-uid multiaccount-data password settings config accounts-data chat-key]
|
||||
@@ -536,6 +519,10 @@
|
||||
[]
|
||||
(.backupDisabledDataDir ^js (status)))
|
||||
|
||||
(defn fleets
|
||||
[]
|
||||
(.fleets ^js (status)))
|
||||
|
||||
(defn keystore-dir
|
||||
[]
|
||||
(.keystoreDir ^js (status)))
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
(ns quo.components.tags.summary-tag.component-spec
|
||||
(:require
|
||||
[quo.components.tags.summary-tag.view :as summary-tag]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Summary tag component tests"
|
||||
(h/test "Basic render"
|
||||
(h/render [summary-tag/view])
|
||||
(h/is-truthy (h/query-by-label-text :container)))
|
||||
|
||||
(h/test "Account view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :account
|
||||
:label "Alice's Account"
|
||||
:customization-color "#ff0000"
|
||||
:emoji "🎉"}])
|
||||
(h/is-truthy (h/get-by-text "Alice's Account")))
|
||||
|
||||
(h/test "Network view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :network
|
||||
:label "Ethereum Network"
|
||||
:image-source "path/to/ethereum-logo.png"}])
|
||||
(h/is-truthy (h/get-by-text "Ethereum Network")))
|
||||
|
||||
(h/test "Saved address view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :saved-address
|
||||
:label "Charlie's Wallet"
|
||||
:customization-color "#00ff00"}])
|
||||
(h/is-truthy (h/get-by-text "Charlie's Wallet")))
|
||||
|
||||
(h/test "Collectible view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :collectible
|
||||
:label "Rare Artifact"
|
||||
:image-source "path/to/artifact-image.png"}])
|
||||
(h/is-truthy (h/get-by-text "Rare Artifact")))
|
||||
|
||||
(h/test "User view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :user
|
||||
:label "Bob Smith"
|
||||
:image-source "path/to/profile-pic.png"
|
||||
:customization-color "#0000ff"}])
|
||||
(h/is-truthy (h/get-by-text "Bob Smith")))
|
||||
|
||||
(h/test "Token view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :token
|
||||
:label "1,000 SNT"
|
||||
:image-source "path/to/token-image.png"}])
|
||||
(h/is-truthy (h/get-by-text "1,000 SNT"))))
|
||||
@@ -1,29 +0,0 @@
|
||||
(ns quo.components.tags.summary-tag.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn main
|
||||
[{:keys [type theme customization-color]}]
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
:height 32
|
||||
:padding-left 4
|
||||
:padding-right 10
|
||||
:flex-direction :row
|
||||
:border-radius (if (#{:account :collectible} type) 10 16)
|
||||
:background-color (colors/resolve-color customization-color theme 10)})
|
||||
|
||||
(defn label
|
||||
[type theme]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:margin-left (if (= type :address) 6 4)})
|
||||
|
||||
(def collectible-image
|
||||
{:width 24
|
||||
:height 24
|
||||
:border-radius 10})
|
||||
|
||||
(def token-image
|
||||
{:width 24
|
||||
:height 24
|
||||
:border-radius 12})
|
||||
@@ -1,67 +0,0 @@
|
||||
(ns quo.components.tags.summary-tag.view
|
||||
(:require
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.summary-tag.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- left-view
|
||||
[{:keys [label type customization-color emoji image-source]}]
|
||||
(case type
|
||||
:account
|
||||
[account-avatar/view
|
||||
{:customization-color customization-color
|
||||
:size 24
|
||||
:emoji emoji
|
||||
:type :default}]
|
||||
:network
|
||||
[rn/image
|
||||
{:source image-source
|
||||
:style style/token-image}]
|
||||
:saved-address
|
||||
[wallet-user-avatar/wallet-user-avatar
|
||||
{:full-name label
|
||||
:size :size-24
|
||||
:customization-color customization-color}]
|
||||
:collectible
|
||||
[rn/image
|
||||
{:source image-source
|
||||
:style style/collectible-image}]
|
||||
:user
|
||||
[user-avatar/user-avatar
|
||||
{:full-name label
|
||||
:size :xs
|
||||
:profile-picture image-source
|
||||
:customization-color customization-color}]
|
||||
:token
|
||||
[rn/image
|
||||
{:source image-source
|
||||
:style style/token-image}]
|
||||
nil))
|
||||
|
||||
(defn- view-internal
|
||||
"Options:
|
||||
- :label - string - tag label
|
||||
- :customization-color - color - It will be passed down to components that
|
||||
should vary based on a custom color.
|
||||
- :type - :token / :user / :collectible / :saved-address / :network / :account
|
||||
- :emoji - string - emoji used for displaying account avatar
|
||||
- :image-source - resource - image to display on :network, :collectible :user and :token
|
||||
- :theme - :light / :dark"
|
||||
[{:keys [label customization-color type theme]
|
||||
:as props
|
||||
:or {customization-color colors/neutral-80-opa-5}}]
|
||||
[rn/view
|
||||
{:accessibility-label :container
|
||||
:style (style/main (assoc props :customization-color customization-color))}
|
||||
[left-view props]
|
||||
[text/text
|
||||
{:style (style/label type theme)
|
||||
:weight :semi-bold
|
||||
:size :heading-1} label]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -131,7 +131,6 @@
|
||||
quo.components.tags.number-tag.view
|
||||
quo.components.tags.permission-tag
|
||||
quo.components.tags.status-tags
|
||||
quo.components.tags.summary-tag.view
|
||||
quo.components.tags.tag
|
||||
quo.components.tags.tags
|
||||
quo.components.tags.tiny-tag.view
|
||||
@@ -361,7 +360,6 @@
|
||||
(def number-tag quo.components.tags.number-tag.view/view)
|
||||
(def permission-tag quo.components.tags.permission-tag/tag)
|
||||
(def status-tag quo.components.tags.status-tags/status-tag)
|
||||
(def summary-tag quo.components.tags.summary-tag.view/view)
|
||||
(def tag quo.components.tags.tag/tag)
|
||||
(def tags quo.components.tags.tags/tags)
|
||||
(def tiny-tag quo.components.tags.tiny-tag.view/view)
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
[quo.components.switchers.group-messaging-card.component-spec]
|
||||
[quo.components.tags.network-tags.component-spec]
|
||||
[quo.components.tags.status-tags-component-spec]
|
||||
[quo.components.tags.summary-tag.component-spec]
|
||||
[quo.components.tags.tiny-tag.component-spec]
|
||||
[quo.components.wallet.account-card.component-spec]
|
||||
[quo.components.wallet.account-origin.component-spec]
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
(ns status-im.contexts.profile.rpc
|
||||
(:require
|
||||
clojure.set
|
||||
[clojure.string :as string]
|
||||
[utils.ens.core :as utils.ens]))
|
||||
|
||||
(defn rpc->wakuv2-config
|
||||
[wakuv2-config]
|
||||
(clojure.set/rename-keys wakuv2-config {:LightClient :light-client}))
|
||||
|
||||
(defn rpc->profiles-overview
|
||||
[{:keys [customizationColor keycard-pairing] :as profile}]
|
||||
(if (map? profile)
|
||||
(-> profile
|
||||
(update :wakuv2-config rpc->wakuv2-config)
|
||||
(dissoc :customizationColor)
|
||||
(assoc :customization-color (keyword customizationColor))
|
||||
(assoc :ens-name? (utils.ens/is-valid-eth-name? (:name profile)))
|
||||
(assoc :keycard-pairing (when-not (string/blank? keycard-pairing) keycard-pairing)))
|
||||
profile))
|
||||
@@ -1,17 +1,26 @@
|
||||
(ns status-im.fleet.core
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.node.core :as node]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(def ^:private default-fleets (transforms/json->clj (native-module/fleets)))
|
||||
(def ^:private default-fleet (:defaultFleet default-fleets))
|
||||
(def fleets
|
||||
(->> default-fleets
|
||||
:fleets
|
||||
keys
|
||||
(map name)))
|
||||
|
||||
(defn current-fleet-sub
|
||||
[multiaccount]
|
||||
(keyword (or (get multiaccount :fleet)
|
||||
config/fleet)))
|
||||
default-fleet)))
|
||||
|
||||
(defn format-mailserver
|
||||
[mailserver address]
|
||||
@@ -78,10 +87,9 @@
|
||||
[{:keys [db now] :as cofx} fleet]
|
||||
(let [old-fleet (get-in db [:profile/profile :fleet])]
|
||||
(when (not= fleet old-fleet)
|
||||
(rf/merge
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
(multiaccounts.update/multiaccount-update :fleet fleet {})
|
||||
(node/prepare-new-config
|
||||
{:on-success
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.update.callback/save-settings-success])})))))
|
||||
:fleet
|
||||
fleet
|
||||
{:on-success
|
||||
#(re-frame/dispatch [:logout])}))))
|
||||
|
||||
@@ -523,8 +523,7 @@
|
||||
(error-object->map response)]))}))
|
||||
|
||||
(defn save-multiaccount-and-login
|
||||
[args]
|
||||
(keycard/save-multiaccount-and-login card args))
|
||||
[_])
|
||||
|
||||
(defn login
|
||||
[args]
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.ethereum.eip.eip55 :as eip55]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
@@ -152,6 +151,7 @@
|
||||
:keycard/check-nfc-enabled nil}
|
||||
(intro-wizard)))
|
||||
|
||||
;; NOTE: currently non functional, keycard needs to be reimplemented
|
||||
(rf/defn create-keycard-multiaccount
|
||||
{:events [::create-keycard-multiaccount]
|
||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
||||
@@ -182,27 +182,7 @@
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] nil)
|
||||
(dissoc :intro-wizard))}
|
||||
(multiaccounts.create/on-multiaccount-created
|
||||
{:recovered (or recovered (get-in db [:intro-wizard :recovering?]))
|
||||
:derived {constants/path-wallet-root-keyword
|
||||
{:public-key wallet-root-public-key
|
||||
:address (eip55/address->checksum wallet-root-address)}
|
||||
constants/path-whisper-keyword
|
||||
{:public-key whisper-public-key
|
||||
:address (eip55/address->checksum whisper-address)}
|
||||
constants/path-default-wallet-keyword
|
||||
{:public-key wallet-public-key
|
||||
:address (eip55/address->checksum wallet-address)}}
|
||||
:address address
|
||||
:public-key public-key
|
||||
:keycard-instance-uid instance-uid
|
||||
:key-uid (address/normalized-hex key-uid)
|
||||
:keycard-pairing pairing
|
||||
:keycard-paired-on paired-on
|
||||
:chat-key whisper-private-key}
|
||||
encryption-public-key
|
||||
{}))))
|
||||
(dissoc :intro-wizard))})))
|
||||
|
||||
(rf/defn return-to-keycard-login
|
||||
[{:keys [db] :as cofx}]
|
||||
|
||||
@@ -489,14 +489,7 @@
|
||||
(log/warn "sign-typed-data not implemented" args))
|
||||
|
||||
(defn save-multiaccount-and-login
|
||||
[{:keys [key-uid multiaccount-data password settings node-config accounts-data]}]
|
||||
(native-module/save-account-and-login
|
||||
key-uid
|
||||
(types/clj->json multiaccount-data)
|
||||
password
|
||||
(types/clj->json settings)
|
||||
node-config
|
||||
(types/clj->json accounts-data)))
|
||||
[_])
|
||||
|
||||
(defn login
|
||||
[{:keys [key-uid multiaccount-data password]}]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.node.core :as node]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -11,13 +10,11 @@
|
||||
[{:keys [db now] :as cofx} log-level]
|
||||
(let [old-log-level (get-in db [:profile/profile :log-level])]
|
||||
(when (not= old-log-level log-level)
|
||||
(rf/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:log-level
|
||||
log-level
|
||||
{})
|
||||
(node/prepare-new-config
|
||||
{:on-success #(re-frame/dispatch [:logout])})))))
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
:log-level
|
||||
log-level
|
||||
{:on-success #(re-frame/dispatch [:logout])}))))
|
||||
|
||||
(rf/defn show-change-log-level-confirmation
|
||||
{:events [:log-level.ui/log-level-selected]}
|
||||
|
||||
@@ -2,17 +2,10 @@
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.data-store.settings :as data-store.settings]
|
||||
[status-im.node.core :as node]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.deprecated-types :as types]
|
||||
[status-im.utils.signing-phrase.core :as signing-phrase]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.ethereum.eip.eip55 :as eip55]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn normalize-derived-data-keys
|
||||
[derived-data]
|
||||
@@ -82,134 +75,3 @@
|
||||
(rf/defn save-multiaccount-and-login-with-keycard
|
||||
[_ args]
|
||||
{:keycard/save-multiaccount-and-login args})
|
||||
|
||||
(re-frame/reg-fx
|
||||
::save-account-and-login
|
||||
(fn [[key-uid multiaccount-data hashed-password settings config accounts-data]]
|
||||
(native-module/save-account-and-login
|
||||
key-uid
|
||||
multiaccount-data
|
||||
hashed-password
|
||||
settings
|
||||
config
|
||||
accounts-data)))
|
||||
|
||||
(rf/defn save-account-and-login
|
||||
[_ key-uid multiaccount-data password settings node-config accounts-data]
|
||||
{::save-account-and-login [key-uid
|
||||
(types/clj->json multiaccount-data)
|
||||
password
|
||||
(types/clj->json settings)
|
||||
node-config
|
||||
(types/clj->json accounts-data)]})
|
||||
|
||||
(defn prepare-accounts-data
|
||||
[multiaccount]
|
||||
[(let [{:keys [public-key address]}
|
||||
(get-in multiaccount [:derived constants/path-default-wallet-keyword])]
|
||||
{:public-key public-key
|
||||
:address (eip55/address->checksum address)
|
||||
:color colors/blue-persist
|
||||
:wallet true
|
||||
:path constants/path-default-wallet
|
||||
:name (i18n/label :t/main-account)})
|
||||
(let [{:keys [compressed-key public-key address name]}
|
||||
(get-in multiaccount [:derived constants/path-whisper-keyword])]
|
||||
{:public-key public-key
|
||||
:compressed-key compressed-key
|
||||
:address (eip55/address->checksum address)
|
||||
:name name
|
||||
:path constants/path-whisper
|
||||
:chat true})])
|
||||
|
||||
(rf/defn on-multiaccount-created
|
||||
[{:keys [signing-phrase random-guid-generator db] :as cofx}
|
||||
{:keys [address chat-key keycard-instance-uid key-uid
|
||||
keycard-pairing keycard-paired-on mnemonic recovered]
|
||||
:as multiaccount}
|
||||
password
|
||||
{:keys [save-mnemonic? login?] :or {login? true save-mnemonic? false}}]
|
||||
(let [[wallet-account
|
||||
{:keys [public-key
|
||||
compressed-key
|
||||
name]} :as accounts-data]
|
||||
(prepare-accounts-data
|
||||
multiaccount)
|
||||
multiaccount-data {:name name
|
||||
:address address
|
||||
:key-uid key-uid
|
||||
:keycard-pairing keycard-pairing}
|
||||
keycard-multiaccount? (boolean keycard-pairing)
|
||||
eip1581-address (get-in multiaccount
|
||||
[:derived
|
||||
constants/path-eip1581-keyword
|
||||
:address])
|
||||
new-multiaccount
|
||||
(cond->
|
||||
(merge
|
||||
{;; address of the master key
|
||||
:address address
|
||||
;; sha256 of master public key
|
||||
:key-uid key-uid
|
||||
;; The address from which we derive any wallet
|
||||
:wallet-root-address
|
||||
(get-in multiaccount
|
||||
[:derived
|
||||
constants/path-wallet-root-keyword
|
||||
:address])
|
||||
:name name
|
||||
;; public key of the chat account
|
||||
:public-key public-key
|
||||
;; compressed key of the chat account
|
||||
:compressed-key compressed-key
|
||||
;; default address for Dapps
|
||||
:dapps-address (:address wallet-account)
|
||||
:latest-derived-path 0
|
||||
:signing-phrase signing-phrase
|
||||
:backup-enabled? true
|
||||
:installation-id (random-guid-generator)
|
||||
;; default mailserver (history node) setting
|
||||
:use-mailservers? true
|
||||
:recovered recovered}
|
||||
config/default-multiaccount)
|
||||
;; The address from which we derive any chat
|
||||
;; account/encryption keys
|
||||
eip1581-address
|
||||
(assoc :eip1581-address eip1581-address)
|
||||
save-mnemonic?
|
||||
(assoc :mnemonic mnemonic)
|
||||
keycard-multiaccount?
|
||||
(assoc :keycard-instance-uid keycard-instance-uid
|
||||
:keycard-pairing keycard-pairing
|
||||
:keycard-paired-on keycard-paired-on))
|
||||
db (assoc db
|
||||
:profile/login {:key-uid key-uid
|
||||
:name name
|
||||
:password password
|
||||
:creating? true
|
||||
:processing true}
|
||||
:profile/profile new-multiaccount
|
||||
:profile/wallet-accounts [wallet-account]
|
||||
:networks/current-network config/default-network
|
||||
:networks/networks (data-store.settings/rpc->networks config/default-networks))
|
||||
settings (assoc new-multiaccount
|
||||
:networks/current-network config/default-network
|
||||
:networks/networks config/default-networks)]
|
||||
(rf/merge cofx
|
||||
{:db db}
|
||||
(if keycard-multiaccount?
|
||||
(save-multiaccount-and-login-with-keycard
|
||||
{:key-uid key-uid
|
||||
:multiaccount-data multiaccount-data
|
||||
:password password
|
||||
:settings settings
|
||||
:node-config (node/get-new-config db)
|
||||
:accounts-data accounts-data
|
||||
:chat-key chat-key})
|
||||
(save-account-and-login
|
||||
key-uid
|
||||
multiaccount-data
|
||||
(native-module/sha3 (security/safe-unmask-data password))
|
||||
settings
|
||||
(node/get-new-config db)
|
||||
accounts-data)))))
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.node.core :as node]
|
||||
[status-im2.navigation.events :as navigation]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -117,12 +116,10 @@
|
||||
(rf/defn save-network-settings
|
||||
{:events [::save-network-settings-pressed]}
|
||||
[{:keys [db] :as cofx} network]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db :networks/current-network network)
|
||||
:json-rpc/call [{:method "settings_saveSetting"
|
||||
:params [:networks/current-network network]
|
||||
:on-success #()}]}
|
||||
(node/prepare-new-config {:on-success #(re-frame/dispatch [:logout])})))
|
||||
{:db (assoc db :networks/current-network network)
|
||||
:json-rpc/call [{:method "settings_saveSetting"
|
||||
:params [:networks/current-network network]
|
||||
:on-success #(re-frame/dispatch [:logout])}]})
|
||||
|
||||
(rf/defn remove-network
|
||||
{:events [::remove-network-confirmed]}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
(ns status-im.node.core
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.utils.deprecated-types :as types]
|
||||
[status-im2.config :as config]
|
||||
[utils.re-frame :as rf]))
|
||||
[status-im2.config :as config]))
|
||||
|
||||
(defn- add-custom-bootnodes
|
||||
[config network all-bootnodes]
|
||||
@@ -195,32 +192,4 @@
|
||||
:always
|
||||
(add-log-level log-level))))
|
||||
|
||||
(defn get-new-config
|
||||
[db]
|
||||
(types/clj->json (get-multiaccount-node-config db)))
|
||||
|
||||
(rf/defn save-new-config
|
||||
"Saves a new status-go config for the current account
|
||||
This RPC method is the only way to change the node config of an account.
|
||||
NOTE: it is better used indirectly through `prepare-new-config`,
|
||||
which will take care of building up the proper config based on settings in
|
||||
app-db"
|
||||
{:events [::save-new-config]}
|
||||
[_ config {:keys [on-success]}]
|
||||
{:json-rpc/call [{:method "settings_saveSetting"
|
||||
:params [:node-config config]
|
||||
:on-success on-success}]})
|
||||
|
||||
(rf/defn prepare-new-config
|
||||
"Use this function to apply settings to the current account node config"
|
||||
[{:keys [db]} {:keys [on-success]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{::prepare-new-config [key-uid
|
||||
(get-new-config db)
|
||||
#(re-frame/dispatch
|
||||
[::save-new-config % {:on-success on-success}])]}))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::prepare-new-config
|
||||
(fn [[key-uid config callback]]
|
||||
(native-module/prepare-dir-and-update-config key-uid config callback)))
|
||||
|
||||
@@ -7,12 +7,17 @@
|
||||
[utils.i18n :as i18n])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[event]
|
||||
(re-frame/dispatch [:bottom-sheet/hide-old])
|
||||
(re-frame/dispatch event))
|
||||
|
||||
(defn- normal-mode-settings-data
|
||||
[{:keys [network-name
|
||||
current-log-level
|
||||
waku-bloom-filter-mode
|
||||
test-networks-enabled?
|
||||
light-client-enabled?
|
||||
transactions-management-enabled?
|
||||
wakuv2-flag
|
||||
current-fleet
|
||||
webview-debug]}]
|
||||
(keep
|
||||
@@ -49,19 +54,12 @@
|
||||
:accessory :text
|
||||
:accessory-text current-fleet
|
||||
:chevron true}
|
||||
(if wakuv2-flag
|
||||
{:size :small
|
||||
:title (i18n/label :t/wakuv2-settings)
|
||||
:accessibility-label :wakuv2-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:wakuv2.ui/enter-settings-pressed])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/bootnodes)
|
||||
:accessibility-label :bootnodes-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :bootnodes-settings])
|
||||
:chevron true})
|
||||
{:size :small
|
||||
:title (i18n/label :t/wakuv2-settings)
|
||||
:accessibility-label :wakuv2-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:wakuv2.ui/enter-settings-pressed])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/rpc-usage-info)
|
||||
:accessibility-label :rpc-usage-info
|
||||
@@ -76,6 +74,15 @@
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :peers-stats])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/light-client-enabled)
|
||||
:accessibility-label :light-client-enabled
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:wakuv2.ui/toggle-light-client (not light-client-enabled?)])
|
||||
:accessory :switch
|
||||
:active light-client-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/transactions-management-enabled)
|
||||
:accessibility-label :transactions-management-enabled
|
||||
@@ -96,14 +103,19 @@
|
||||
:accessory :switch
|
||||
:active webview-debug}
|
||||
{:size :small
|
||||
:title (i18n/label :t/waku-bloom-filter-mode)
|
||||
:accessibility-label :waku-bloom-filter-mode-settings-switch
|
||||
:title "Testnet mode"
|
||||
:accessibility-label :test-networks-enabled
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/waku-bloom-filter-mode-switched (not waku-bloom-filter-mode)])
|
||||
#(re-frame/dispatch [:profile.settings/toggle-test-networks])
|
||||
:accessory :switch
|
||||
:active waku-bloom-filter-mode}]))
|
||||
:active test-networks-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/set-currency)
|
||||
:accessibility-label :wallet-change-currency
|
||||
:on-press #(hide-sheet-and-dispatch
|
||||
[:navigate-to :currency-settings])
|
||||
:chevron true}]))
|
||||
|
||||
(defn- flat-list-data
|
||||
[options]
|
||||
@@ -117,10 +129,10 @@
|
||||
|
||||
(views/defview advanced-settings
|
||||
[]
|
||||
(views/letsubs [{:keys [webview-debug]} [:profile/profile]
|
||||
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
|
||||
light-client-enabled? [:profile/light-client-enabled?]
|
||||
webview-debug [:profile/webview-debug]
|
||||
network-name [:network-name]
|
||||
waku-bloom-filter-mode [:waku/bloom-filter-mode]
|
||||
wakuv2-flag [:waku/v2-flag]
|
||||
transactions-management-enabled? [:wallet-legacy/transactions-management-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
current-fleet [:fleets/current-fleet]]
|
||||
@@ -129,10 +141,10 @@
|
||||
{:network-name network-name
|
||||
:current-log-level current-log-level
|
||||
:transactions-management-enabled? transactions-management-enabled?
|
||||
:light-client-enabled? light-client-enabled?
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:wakuv2-flag wakuv2-flag
|
||||
:waku-bloom-filter-mode waku-bloom-filter-mode
|
||||
:webview-debug webview-debug})
|
||||
:webview-debug webview-debug
|
||||
:test-networks-enabled? test-networks-enabled?})
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn render-item}]))
|
||||
|
||||
@@ -225,7 +225,9 @@
|
||||
(.. ^js % -nativeEvent -data)])
|
||||
:on-load #(re-frame/dispatch [:browser/loading-started])
|
||||
:on-error #(re-frame/dispatch [:browser/error-occured])
|
||||
:injected-java-script-before-content-loaded (js-res/ethereum-provider (str network-id))}])]
|
||||
:injected-java-script-before-content-loaded (js-res/ethereum-provider (str network-id))
|
||||
;; https://github.com/status-im/status-mobile/issues/17854
|
||||
:allows-inline-media-playback true}])]
|
||||
[navigation
|
||||
{:url url-original
|
||||
:name name
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns status-im.ui.screens.fleet-settings.views
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.node.core :as node]
|
||||
[status-im.fleet.core :as fleets]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
@@ -30,16 +30,11 @@
|
||||
[react/text {:style styles/fleet-item-name-text}
|
||||
fleet]]]]))
|
||||
|
||||
(defn fleets
|
||||
[custom-fleets]
|
||||
(map name (keys (node/fleets {:custom-fleets custom-fleets}))))
|
||||
|
||||
(views/defview fleet-settings
|
||||
[]
|
||||
(views/letsubs [custom-fleets [:fleets/custom-fleets]
|
||||
current-fleet [:fleets/current-fleet]]
|
||||
(views/letsubs [current-fleet [:fleets/current-fleet]]
|
||||
[list/flat-list
|
||||
{:data (fleets custom-fleets)
|
||||
{:data fleets/fleets
|
||||
:default-separator? false
|
||||
:key-fn identity
|
||||
:render-data (name current-fleet)
|
||||
|
||||
@@ -117,6 +117,9 @@
|
||||
:isAddress
|
||||
(fn [address] (.isAddress native-status address))
|
||||
|
||||
:fleets
|
||||
(fn [] (.fleets native-status))
|
||||
|
||||
:validateMnemonic
|
||||
(fn [json callback] (callback (.validateMnemonic native-status json)))
|
||||
|
||||
|
||||
@@ -2,22 +2,11 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.node.core :as node]
|
||||
[status-im2.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn switch-waku-bloom-filter-mode
|
||||
{:events [:multiaccounts.ui/waku-bloom-filter-mode-switched]}
|
||||
[cofx enabled?]
|
||||
(rf/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:waku-bloom-filter-mode
|
||||
enabled?
|
||||
{})
|
||||
(node/prepare-new-config
|
||||
{:on-success #(re-frame/dispatch [:logout])})))
|
||||
|
||||
(def address-regex #"/ip4/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/tcp/\d{1,5}/p2p/[a-zA-Z0-9]+")
|
||||
|
||||
@@ -108,13 +97,16 @@
|
||||
vals
|
||||
(map #(vector (:name %1) (:address %1)))
|
||||
(into {}))]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/profile :wakuv2-config :CustomNodes] new-nodes)
|
||||
(dissoc :wakuv2-nodes/manage :wakuv2-nodes/list))
|
||||
:dispatch [:navigate-back]}
|
||||
(node/prepare-new-config
|
||||
{:on-success #(re-frame/dispatch [:logout])}))))
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/profile :wakuv2-config :CustomNodes] new-nodes)
|
||||
(dissoc :wakuv2-nodes/manage :wakuv2-nodes/list))
|
||||
:json-rpc/call [{:method "wakuext_setCustomNodes"
|
||||
:params [{:customNodes new-nodes}]
|
||||
:on-success #(log/info "updated custom nodes")
|
||||
:on-error #(log/error "failed to set custom nodes"
|
||||
{:error %
|
||||
:custom-nodes new-nodes})}]
|
||||
:dispatch [:navigate-back]}))
|
||||
|
||||
(rf/defn show-delete-node-confirmation
|
||||
{:events [:wakuv2.ui/delete-pressed]}
|
||||
@@ -131,3 +123,17 @@
|
||||
(rf/merge cofx
|
||||
(delete id)
|
||||
(navigation/navigate-back)))
|
||||
|
||||
(rf/defn toggle-light-client
|
||||
{:events [:wakuv2.ui/toggle-light-client]}
|
||||
[{:keys [db]} enabled?]
|
||||
{:db (assoc-in db [:profile/profile :wakuv2-config :LightClient] enabled?)
|
||||
|
||||
:json-rpc/call [{:method "wakuext_setLightClient"
|
||||
:params [{:enabled enabled?}]
|
||||
:on-success (fn []
|
||||
(log/info "light client set successfully" enabled?)
|
||||
(re-frame/dispatch [:logout]))
|
||||
:on-error #(log/error "failed to set light client"
|
||||
{:error %
|
||||
:enabled? enabled?})}]})
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
[status-im2.common.confirmation-drawer.view :as confirmation-drawer]
|
||||
[status-im2.common.mute-drawer.view :as mute-drawer]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.communities.actions.chat.view :as chat-actions]
|
||||
[status-im2.contexts.chat.actions.view :as chat-actions]
|
||||
[status-im2.contexts.communities.actions.chat.view :as communities-chat-actions]
|
||||
[status-im2.contexts.contacts.drawers.nickname-drawer.view :as nickname-drawer]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -253,16 +255,6 @@
|
||||
:chevron? true
|
||||
:add-divider? add-divider?}))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn fetch-messages-entry
|
||||
[]
|
||||
(entry {:icon :i/save
|
||||
:label (i18n/label :t/fetch-messages)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
:danger? false
|
||||
:accessibility-label :fetch-messages
|
||||
:sub-label nil
|
||||
:chevron? true}))
|
||||
|
||||
(defn remove-from-contacts-entry
|
||||
[contact]
|
||||
@@ -419,9 +411,9 @@
|
||||
[(mark-as-read-entry chat-id needs-divider?)
|
||||
(mute-chat-entry chat-id chat-type muted-till)
|
||||
(notifications-entry false)
|
||||
(when inside-chat?
|
||||
(fetch-messages-entry))
|
||||
(when (or (not group-chat) public?)
|
||||
(when (and config/fetch-messages-enabled? inside-chat?)
|
||||
(chat-actions/fetch-messages chat-id))
|
||||
(when public?
|
||||
(show-qr-entry))
|
||||
(when-not group-chat
|
||||
(share-profile-entry))
|
||||
@@ -481,7 +473,7 @@
|
||||
constants/private-group-chat-type
|
||||
[private-group-chat-actions chat inside-chat?]
|
||||
constants/community-chat-type
|
||||
[chat-actions/actions chat inside-chat?]
|
||||
[communities-chat-actions/actions chat inside-chat?]
|
||||
nil))
|
||||
|
||||
(defn group-details-actions
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
(ns status-im2.common.standard-authentication.core
|
||||
(:require
|
||||
status-im2.common.standard-authentication.standard-auth.button.view
|
||||
status-im2.common.standard-authentication.standard-auth.slide-button.view))
|
||||
|
||||
(def button status-im2.common.standard-authentication.standard-auth.button.view/view)
|
||||
(def slide-button status-im2.common.standard-authentication.standard-auth.slide-button.view/view)
|
||||
+1
-41
@@ -1,10 +1,6 @@
|
||||
(ns status-im2.common.standard-authentication.standard-auth.view
|
||||
(ns status-im2.common.standard-authentication.standard-auth.authorize
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.touch-id :as biometric]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.standard-authentication.enter-password.view :as enter-password]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -46,39 +42,3 @@
|
||||
{:on-enter-password on-enter-password
|
||||
:button-icon-left auth-button-icon-left
|
||||
:button-label auth-button-label}])}]))))))
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(let [reset-slider? (reagent/atom false)
|
||||
on-close #(reset! reset-slider? true)]
|
||||
(fn [{:keys [biometric-auth?
|
||||
track-text
|
||||
customization-color
|
||||
auth-button-label
|
||||
on-enter-password
|
||||
on-auth-success
|
||||
on-auth-fail
|
||||
auth-button-icon-left
|
||||
size
|
||||
theme
|
||||
blur?
|
||||
container-style]}]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[quo/slide-button
|
||||
{:size size
|
||||
:container-style container-style
|
||||
:customization-color customization-color
|
||||
:on-reset (when @reset-slider? #(reset! reset-slider? false))
|
||||
:on-complete #(authorize {:on-close on-close
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:on-enter-password on-enter-password
|
||||
:biometric-auth? biometric-auth?
|
||||
:on-auth-success on-auth-success
|
||||
:on-auth-fail on-auth-fail
|
||||
:auth-button-label auth-button-label})
|
||||
:track-icon (if biometric-auth? :i/face-id :password)
|
||||
:track-text track-text}]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -0,0 +1,44 @@
|
||||
(ns status-im2.common.standard-authentication.standard-auth.button.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.standard-authentication.standard-auth.authorize :as authorize]))
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(let [reset-slider? (reagent/atom false)
|
||||
on-close #(reset! reset-slider? true)]
|
||||
(fn [{:keys [biometric-auth?
|
||||
customization-color
|
||||
auth-button-label
|
||||
on-enter-password
|
||||
on-auth-success
|
||||
on-press
|
||||
on-auth-fail
|
||||
auth-button-icon-left
|
||||
size
|
||||
button-label
|
||||
theme
|
||||
blur?
|
||||
container-style
|
||||
icon-left]}]
|
||||
[quo/button
|
||||
{:size size
|
||||
:container-style container-style
|
||||
:customization-color customization-color
|
||||
:icon-left icon-left
|
||||
:on-press (if on-press
|
||||
on-press
|
||||
#(authorize/authorize {:on-close on-close
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:on-enter-password on-enter-password
|
||||
:biometric-auth? biometric-auth?
|
||||
:on-auth-success on-auth-success
|
||||
:on-auth-fail on-auth-fail
|
||||
:auth-button-label auth-button-label}))}
|
||||
button-label])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -0,0 +1,43 @@
|
||||
(ns status-im2.common.standard-authentication.standard-auth.slide-button.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.standard-authentication.standard-auth.authorize :as authorize]))
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(let [reset-slider? (reagent/atom false)
|
||||
on-close #(reset! reset-slider? true)]
|
||||
(fn [{:keys [biometric-auth?
|
||||
track-text
|
||||
customization-color
|
||||
auth-button-label
|
||||
on-enter-password
|
||||
on-auth-success
|
||||
on-auth-fail
|
||||
auth-button-icon-left
|
||||
size
|
||||
theme
|
||||
blur?
|
||||
container-style]}]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[quo/slide-button
|
||||
{:size size
|
||||
:container-style container-style
|
||||
:customization-color customization-color
|
||||
:on-reset (when @reset-slider? #(reset! reset-slider? false))
|
||||
:on-complete #(authorize/authorize {:on-close on-close
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:on-enter-password on-enter-password
|
||||
:biometric-auth? biometric-auth?
|
||||
:on-auth-success on-auth-success
|
||||
:on-auth-fail on-auth-fail
|
||||
:auth-button-label auth-button-label})
|
||||
:track-icon (if biometric-auth? :i/face-id :password)
|
||||
:track-text track-text}]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -170,3 +170,5 @@
|
||||
(def default-kdf-iterations 3200)
|
||||
|
||||
(def shell-navigation-disabled? false)
|
||||
(def community-accounts-selection-enabled? false)
|
||||
(def fetch-messages-enabled? (enabled? (get-config :FETCH_MESSAGES_ENABLED "1")))
|
||||
|
||||
@@ -4,6 +4,16 @@
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn fetch-messages
|
||||
[chat-id]
|
||||
{:icon :i/download
|
||||
:right-icon :i/chevron-right
|
||||
:accessibility-label :chat-fetch-messages
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:chat/fetch-messages chat-id]))
|
||||
:label (i18n/label :t/fetch-messages)})
|
||||
|
||||
(defn new-chat
|
||||
[]
|
||||
[quo/action-drawer
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn edit-message
|
||||
[state]
|
||||
[{:keys [text-value input-ref]}]
|
||||
[rn/view
|
||||
{:style style/container
|
||||
:accessibility-label :edit-message}
|
||||
@@ -30,20 +30,18 @@
|
||||
{:size 24
|
||||
:icon-only? true
|
||||
:accessibility-label :edit-cancel-button
|
||||
:on-press (fn []
|
||||
(utils/cancel-edit-message state)
|
||||
(rf/dispatch [:chat.ui/cancel-message-edit]))
|
||||
:on-press #(utils/cancel-edit-message text-value input-ref)
|
||||
:type :outline}
|
||||
:i/close]])
|
||||
|
||||
(defn- f-view
|
||||
[state]
|
||||
[props]
|
||||
(let [edit (rf/sub [:chats/edit-message])
|
||||
height (reanimated/use-shared-value (if edit constants/edit-container-height 0))]
|
||||
(rn/use-effect #(reanimated/animate height (if edit constants/edit-container-height 0)) [edit])
|
||||
[reanimated/view {:style (reanimated/apply-animations-to-style {:height height} {})}
|
||||
(when edit [edit-message state])]))
|
||||
(when edit [edit-message props])]))
|
||||
|
||||
(defn view
|
||||
[state]
|
||||
[:f> f-view state])
|
||||
[props]
|
||||
[:f> f-view props])
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.chat.composer.constants :as constants]
|
||||
[status-im2.contexts.chat.composer.keyboard :as kb]
|
||||
[status-im2.contexts.chat.composer.utils :as utils]
|
||||
@@ -105,25 +106,48 @@
|
||||
|
||||
(defn use-edit
|
||||
[{:keys [input-ref]}
|
||||
{:keys [text-value saved-cursor-position]}
|
||||
{:keys [edit]}
|
||||
{:keys [text-value saved-cursor-position cursor-position]}
|
||||
{:keys [edit input-with-mentions]}
|
||||
messages-list-on-layout-finished?]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(let [edit-text (get-in edit [:content :text])
|
||||
text-value-count (count @text-value)]
|
||||
(when @messages-list-on-layout-finished?
|
||||
;; A small setTimeout is necessary to ensure the statement is enqueued and will get
|
||||
;; executed
|
||||
;; ASAP. Https://github.com/software-mansion/react-native-screens/issues/472
|
||||
(reset! saved-cursor-position (if edit-text
|
||||
(count edit-text)
|
||||
text-value-count))
|
||||
(js/setTimeout #(.focus ^js @input-ref) 250))
|
||||
(when (and edit @input-ref)
|
||||
(.setNativeProps ^js @input-ref (clj->js {:text edit-text}))
|
||||
(reset! text-value edit-text))))
|
||||
[(:message-id edit)]))
|
||||
(let [mention? (some #(= :mention (first %)) (seq input-with-mentions))
|
||||
composer-just-opened? (not @messages-list-on-layout-finished?)]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(let [mention-text (reduce (fn [acc item]
|
||||
(str acc (second item)))
|
||||
""
|
||||
input-with-mentions)
|
||||
edit-text (cond
|
||||
mention? mention-text
|
||||
;; NOTE: using text-value for cases when the user
|
||||
;; leaves the app with an unfinished edit and re-opens
|
||||
;; the chat.
|
||||
(and (seq @text-value) composer-just-opened?)
|
||||
@text-value
|
||||
:else (get-in edit [:content :text]))
|
||||
selection-pos (count edit-text)
|
||||
inject-edit-text (fn []
|
||||
(reset! text-value edit-text)
|
||||
(reset! cursor-position selection-pos)
|
||||
(reset! saved-cursor-position selection-pos)
|
||||
(when @input-ref
|
||||
(.setNativeProps ^js @input-ref
|
||||
(clj->js {:text edit-text}))))]
|
||||
|
||||
(when (and edit @input-ref)
|
||||
;; NOTE: A small setTimeout is necessary to ensure the focus is enqueued and is executed
|
||||
;; ASAP. Check https://github.com/software-mansion/react-native-screens/issues/472
|
||||
;;
|
||||
;; The nested setTimeout is necessary to avoid both `on-focus` and
|
||||
;; `on-content-size-change` handlers triggering the height animation simultaneously, as
|
||||
;; this causes a jump in the
|
||||
;; UI. This way, `on-focus` will trigger first without changing the height, after which
|
||||
;; `on-content-size-change` will animate the height of the input based on the injected
|
||||
;; text.
|
||||
(js/setTimeout #(do (when @messages-list-on-layout-finished? (.focus ^js @input-ref))
|
||||
(reagent/next-tick inject-edit-text))
|
||||
600))))
|
||||
[(:message-id edit)])))
|
||||
|
||||
(defn use-reply
|
||||
[{:keys [input-ref]}
|
||||
@@ -135,25 +159,8 @@
|
||||
(when reply
|
||||
(reanimated/animate container-opacity 1))
|
||||
(when (and reply @input-ref @messages-list-on-layout-finished?)
|
||||
(js/setTimeout #(.focus ^js @input-ref) 250))))
|
||||
[(:message-id reply)])
|
||||
|
||||
(defn edit-mentions
|
||||
[{:keys [input-ref]} {:keys [text-value cursor-position]} {:keys [input-with-mentions]}]
|
||||
(rn/use-effect (fn []
|
||||
(let [input-text (reduce (fn [acc item]
|
||||
(str acc (second item)))
|
||||
""
|
||||
input-with-mentions)]
|
||||
(reset! text-value input-text)
|
||||
(reset! cursor-position (count input-text))
|
||||
(js/setTimeout #(when @input-ref
|
||||
(.setNativeProps ^js @input-ref
|
||||
(clj->js {:selection {:start (count input-text)
|
||||
:end (count
|
||||
input-text)}})))
|
||||
300)))
|
||||
[(some #(= :mention (first %)) (seq input-with-mentions))]))
|
||||
(js/setTimeout #(.focus ^js @input-ref) 600)))
|
||||
[(:message-id reply)]))
|
||||
|
||||
(defn update-input-mention
|
||||
[{:keys [input-ref]}
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
(reset! emoji-kb-extra-height nil))
|
||||
(reset! maximized? false)
|
||||
(rf/dispatch [:chat.ui/set-input-maximized false])
|
||||
(when @input-ref
|
||||
(.blur ^js @input-ref)))
|
||||
(utils/blur-input input-ref))
|
||||
|
||||
(defn bounce-back
|
||||
[{:keys [height saved-height opacity background-y]}
|
||||
@@ -96,13 +95,13 @@
|
||||
max-height
|
||||
bounded-height
|
||||
saved-height))
|
||||
(when @input-ref ; sheet at min-height, collapse keyboard
|
||||
(.blur ^js @input-ref)))))))
|
||||
; sheet at min-height, collapse keyboard
|
||||
(utils/blur-input input-ref))))))
|
||||
(gesture/on-end (fn []
|
||||
(let [diff (- (reanimated/get-shared-value height)
|
||||
(reanimated/get-shared-value saved-height))]
|
||||
(if @gesture-enabled?
|
||||
(if (>= diff 0)
|
||||
(if (and @expanding? (>= diff 0))
|
||||
(if (> diff constants/drag-threshold)
|
||||
(maximize state animations dimensions)
|
||||
(bounce-back animations dimensions starting-opacity))
|
||||
|
||||
@@ -23,12 +23,14 @@
|
||||
show-floating-scroll-down-button?]
|
||||
(reset! focused? true)
|
||||
(rf/dispatch [:chat.ui/set-input-focused true])
|
||||
(reanimated/animate height (reanimated/get-shared-value last-height))
|
||||
(reanimated/set-shared-value saved-height (reanimated/get-shared-value last-height))
|
||||
(reanimated/animate container-opacity 1)
|
||||
(when (> (reanimated/get-shared-value last-height) (* constants/background-threshold max-height))
|
||||
(reanimated/animate opacity 1)
|
||||
(reanimated/set-shared-value background-y 0))
|
||||
(let [last-height-value (reanimated/get-shared-value last-height)]
|
||||
(reanimated/animate height last-height-value)
|
||||
(reanimated/set-shared-value saved-height last-height-value)
|
||||
(reanimated/animate container-opacity 1)
|
||||
(when (> last-height-value (* constants/background-threshold max-height))
|
||||
(reanimated/animate opacity 1)
|
||||
(reanimated/set-shared-value background-y 0)))
|
||||
|
||||
(js/setTimeout #(reset! lock-selection? false) 300)
|
||||
(when (and (not-empty @text-value) @input-ref)
|
||||
(.setNativeProps ^js @input-ref
|
||||
@@ -72,7 +74,7 @@
|
||||
"Save new text height, expand composer if possible, show background overlay if needed"
|
||||
[event
|
||||
{:keys [maximized? lock-layout? text-value]}
|
||||
{:keys [height saved-height opacity background-y]}
|
||||
{:keys [height saved-height last-height opacity background-y]}
|
||||
{:keys [content-height window-height max-height]}
|
||||
keyboard-shown]
|
||||
(when keyboard-shown
|
||||
@@ -87,8 +89,9 @@
|
||||
max-height)
|
||||
new-height (min new-height max-height)]
|
||||
(reset! content-height content-size)
|
||||
(when (utils/update-height? content-size height max-height maximized?)
|
||||
(when (utils/update-height? content-size height max-height)
|
||||
(reanimated/animate height new-height)
|
||||
(reanimated/set-shared-value last-height new-height)
|
||||
(reanimated/set-shared-value saved-height new-height))
|
||||
(when (= new-height max-height)
|
||||
(reset! maximized? true)
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
[react-native.async-storage :as async-storage]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.contexts.chat.composer.utils :as utils]))
|
||||
|
||||
(defn get-kb-height
|
||||
[curr-height default-height]
|
||||
@@ -20,18 +21,24 @@
|
||||
(async-storage/set-item! :kb-default-height (str height)))))
|
||||
|
||||
(defn handle-emoji-kb-ios
|
||||
"Opening emoji KB on iOS while maximized will cause a flicker up and down. This method handles that."
|
||||
"Opening emoji KB on iOS will cause a flicker up and down due to height differences.
|
||||
This method handles that by adding the extra difference between the keyboards. When the input is
|
||||
expanded to a point where the added difference will make the composer go beyond the screen causing a flicker,
|
||||
we're subtracting the difference so it only reaches the allowed max-height. We're not animating these
|
||||
changes to make it appear seamless during transitions between keyboard types when maximized."
|
||||
[event
|
||||
{:keys [emoji-kb-extra-height]}
|
||||
{:keys [text-value]}
|
||||
{:keys [text-value kb-height]}
|
||||
{:keys [height saved-height]}
|
||||
{:keys [max-height]}]
|
||||
(let [start-h (oops/oget event "startCoordinates.height")
|
||||
end-h (oops/oget event "endCoordinates.height")
|
||||
diff (- end-h start-h)
|
||||
max-height-diff (- max-height diff)
|
||||
curr-text @text-value]
|
||||
(if (> (reanimated/get-shared-value height) max-height-diff)
|
||||
(let [start-h (oops/oget event "startCoordinates.height")
|
||||
end-h (oops/oget event "endCoordinates.height")
|
||||
diff (- end-h start-h)
|
||||
max-height-diff (- max-height diff)
|
||||
curr-text @text-value
|
||||
bigger-than-default-kb? (> end-h @kb-height)
|
||||
almost-expanded? (> (reanimated/get-shared-value height) max-height-diff)]
|
||||
(if (and almost-expanded? bigger-than-default-kb? (pos? diff))
|
||||
(do
|
||||
(reanimated/set-shared-value height (- (reanimated/get-shared-value height) diff))
|
||||
(reanimated/set-shared-value saved-height (- (reanimated/get-shared-value saved-height) diff))
|
||||
@@ -58,8 +65,8 @@
|
||||
#(handle-emoji-kb-ios % props state animations dimensions)))
|
||||
(reset! keyboard-hide-listener (.addListener rn/keyboard
|
||||
"keyboardDidHide"
|
||||
#(when (and platform/android? @input-ref)
|
||||
(.blur ^js @input-ref)))))
|
||||
#(when platform/android?
|
||||
(utils/blur-input input-ref)))))
|
||||
|
||||
(defn handle-refocus-emoji-kb-ios
|
||||
[{:keys [saved-emoji-kb-extra-height]}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
[status-im2.constants :as constant]
|
||||
[status-im2.contexts.chat.composer.constants :as constants]
|
||||
[status-im2.contexts.chat.composer.reply.style :as style]
|
||||
[status-im2.contexts.chat.composer.utils :as utils]
|
||||
[utils.ens.stateofus :as stateofus]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -85,7 +86,7 @@
|
||||
(defn quoted-message
|
||||
[{:keys [from content-type contentType parsed-text content deleted? deleted-for-me?
|
||||
album-images-count]}
|
||||
in-chat-input? pin? recording-audio?]
|
||||
in-chat-input? pin? recording-audio? input-ref]
|
||||
(let [[primary-name _] (rf/sub [:contacts/contact-two-names-by-identity from])
|
||||
current-public-key (rf/sub [:multiaccount/public-key])
|
||||
content-type (or content-type contentType)
|
||||
@@ -136,7 +137,7 @@
|
||||
{:icon-only? true
|
||||
:size 24
|
||||
:accessibility-label :reply-cancel-button
|
||||
:on-press #(rf/dispatch [:chat.ui/cancel-message-reply])
|
||||
:on-press #(utils/cancel-reply-message input-ref)
|
||||
:type :outline}
|
||||
:i/close])
|
||||
(when (and in-chat-input? recording-audio?)
|
||||
@@ -148,13 +149,13 @@
|
||||
:style style/gradient}])]))
|
||||
|
||||
(defn- f-view
|
||||
[recording?]
|
||||
[recording? input-ref]
|
||||
(let [reply (rf/sub [:chats/reply-message])
|
||||
height (reanimated/use-shared-value (if reply constants/reply-container-height 0))]
|
||||
(rn/use-effect #(reanimated/animate height (if reply constants/reply-container-height 0)) [reply])
|
||||
[reanimated/view {:style (reanimated/apply-animations-to-style {:height height} {})}
|
||||
(when reply [quoted-message reply true false recording?])]))
|
||||
(when reply [quoted-message reply true false recording? input-ref])]))
|
||||
|
||||
(defn view
|
||||
[{:keys [recording?]}]
|
||||
[:f> f-view @recording?])
|
||||
[{:keys [recording?]} input-ref]
|
||||
[:f> f-view @recording? input-ref])
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
(max min-v (min v max-v)))
|
||||
|
||||
(defn update-height?
|
||||
[content-size height max-height maximized?]
|
||||
(when-not @maximized?
|
||||
(let [diff (Math/abs (- content-size (reanimated/get-shared-value height)))]
|
||||
(and (not= (reanimated/get-shared-value height) max-height)
|
||||
(> diff constants/content-change-threshold)))))
|
||||
[content-size height max-height]
|
||||
(let [diff (Math/abs (- content-size (reanimated/get-shared-value height)))]
|
||||
(and (not= (reanimated/get-shared-value height) max-height)
|
||||
(> diff constants/content-change-threshold))))
|
||||
|
||||
(defn show-top-gradient?
|
||||
[y lines max-lines gradient-opacity focused?]
|
||||
@@ -100,10 +99,28 @@
|
||||
(not reply?)
|
||||
(not audio?)))
|
||||
|
||||
(defn blur-input
|
||||
[input-ref]
|
||||
(when @input-ref
|
||||
(rf/dispatch [:chat.ui/set-input-focused false])
|
||||
(.blur ^js @input-ref)))
|
||||
|
||||
(defn cancel-reply-message
|
||||
[input-ref]
|
||||
(js/setTimeout #(blur-input input-ref) 100)
|
||||
(rf/dispatch [:chat.ui/set-input-content-height constants/input-height])
|
||||
(rf/dispatch [:chat.ui/cancel-message-reply]))
|
||||
|
||||
(defn cancel-edit-message
|
||||
[{:keys [text-value]}]
|
||||
[text-value input-ref]
|
||||
(reset! text-value "")
|
||||
(rf/dispatch [:chat.ui/set-input-content-height constants/input-height]))
|
||||
;; NOTE: adding a timeout to assure the input is blurred on the next tick
|
||||
;; after the `text-value` was cleared. Otherwise the height will be calculated
|
||||
;; with the old `text-value`, leading to wrong composer height after blur.
|
||||
(js/setTimeout #(blur-input input-ref) 100)
|
||||
(.setNativeProps ^js @input-ref (clj->js {:text ""}))
|
||||
(rf/dispatch [:chat.ui/set-input-content-height constants/input-height])
|
||||
(rf/dispatch [:chat.ui/cancel-message-edit]))
|
||||
|
||||
(defn count-lines
|
||||
[s]
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
(effects/use-edit props state subscriptions messages-list-on-layout-finished?)
|
||||
(effects/use-reply props animations subscriptions messages-list-on-layout-finished?)
|
||||
(effects/update-input-mention props state subscriptions)
|
||||
(effects/edit-mentions props state subscriptions)
|
||||
(effects/link-previews props state animations subscriptions)
|
||||
(effects/use-images props state animations subscriptions)
|
||||
[:<>
|
||||
@@ -99,8 +98,10 @@
|
||||
[sub-view/bar]
|
||||
(when chat-screen-loaded?
|
||||
[:<>
|
||||
[reply/view state]
|
||||
[edit/view state]])
|
||||
[reply/view state (:input-ref props)]
|
||||
[edit/view
|
||||
{:text-value (:text-value state)
|
||||
:input-ref (:input-ref props)}]])
|
||||
[reanimated/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press (fn []
|
||||
@@ -153,7 +154,8 @@
|
||||
(let [window-height (:height (rn/get-window))
|
||||
theme (quo.theme/use-theme-value)
|
||||
opacity (reanimated/use-shared-value 0)
|
||||
background-y (reanimated/use-shared-value (- window-height)) ; Y position of background overlay
|
||||
background-y (reanimated/use-shared-value (- window-height)) ; Y position of background
|
||||
; overlay
|
||||
blur-height (reanimated/use-shared-value (+ constants/composer-default-height
|
||||
(:bottom insets)))
|
||||
extra-params {:insets insets
|
||||
|
||||
@@ -449,3 +449,20 @@
|
||||
{:events [:chat/check-last-chat]}
|
||||
[{:keys [db]}]
|
||||
{:chat/open-last-chat (get-in db [:profile/profile :key-uid])})
|
||||
|
||||
(rf/defn status-tag-pressed
|
||||
{:events [:communities/status-tag-pressed]}
|
||||
[{:keys [db] :as cofx} community-id literal]
|
||||
(let [{:keys [id]} (some #(when (= (:name %) literal) %)
|
||||
(vals (get-in db [:communities community-id :chats])))]
|
||||
(when (and id
|
||||
(not= (:current-chat-id db) (str community-id id)))
|
||||
(navigate-to-chat cofx (str community-id id) nil))))
|
||||
|
||||
(rf/defn fetch-messages
|
||||
{:events [:chat/fetch-messages]}
|
||||
[_ chat-id]
|
||||
{:json-rpc/call [{:method "wakuext_fetchMessages"
|
||||
:params [{:id chat-id}]
|
||||
:on-success #()
|
||||
:on-error #(log/error "failed to fetch messages for chat" chat-id %)}]})
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
[utils.re-frame :as rf]
|
||||
[utils.url :as url]))
|
||||
|
||||
;; these constants are used when there is no width or height defined for a specific image
|
||||
(def ^:const fallback-image-width 1000)
|
||||
(def ^:const fallback-image-height 1000)
|
||||
|
||||
(defn calculate-dimensions
|
||||
[width height max-container-width max-container-height]
|
||||
(let [max-width (if (> width height) max-container-width (* 1.5 constants/image-size))
|
||||
@@ -15,7 +19,12 @@
|
||||
{:width (min width max-width) :height (min height max-height)}))
|
||||
|
||||
(defn image-message
|
||||
[index {:keys [content image-width image-height message-id] :as message} {:keys [on-long-press]}
|
||||
[index
|
||||
{:keys [content image-width image-height message-id]
|
||||
:as message
|
||||
:or {image-width fallback-image-width
|
||||
image-height fallback-image-height}}
|
||||
{:keys [on-long-press]}
|
||||
message-container-data]
|
||||
(let [insets (safe-area/get-insets)
|
||||
{:keys [window-width padding-left padding-right avatar-container-width
|
||||
|
||||
@@ -412,7 +412,15 @@
|
||||
;;TODO(rasom) https://github.com/facebook/react-native/issues/30034
|
||||
:inverted (when platform/ios? true)
|
||||
:on-layout (fn [e]
|
||||
(reset! messages-list-on-layout-finished? true)
|
||||
;; FIXME: the 1s timeout is to assure all effects with
|
||||
;; timeouts that depend on the value are considered.
|
||||
;; Hacky, but we're heavily relying on timeouts in the
|
||||
;; composer and need to react to differently (e.g.
|
||||
;; inside effects/use-edit) when the chat has just
|
||||
;; opened and the subsequent times.
|
||||
(js/setTimeout #(reset! messages-list-on-layout-finished?
|
||||
true)
|
||||
1000)
|
||||
(let [layout-height (oops/oget e
|
||||
"nativeEvent.layout.height")]
|
||||
(reset! messages-view-height layout-height)))
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
[status-im2.common.mute-drawer.view :as mute-drawer]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.contexts.chat.actions.view :as chat-actions]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -83,13 +85,6 @@
|
||||
:on-press not-implemented/alert
|
||||
:label (i18n/label :t/pinned-messages)})
|
||||
|
||||
(defn- action-fetch-messages
|
||||
[]
|
||||
{:icon :i/download
|
||||
:right-icon :i/chevron-right
|
||||
:accessibility-label :chat-fetch-messages
|
||||
:on-press not-implemented/alert
|
||||
:label (i18n/label :t/fetch-messages)})
|
||||
|
||||
(defn- action-invite-people
|
||||
[]
|
||||
@@ -141,7 +136,8 @@
|
||||
(action-mark-as-read)
|
||||
(action-toggle-muted chat-id muted muted-till chat-type)
|
||||
(action-notification-settings)
|
||||
(action-fetch-messages)
|
||||
(when config/fetch-messages-enabled?
|
||||
(chat-actions/fetch-messages chat-id))
|
||||
(action-invite-people)
|
||||
(action-qr-code)
|
||||
(action-share)]]]
|
||||
|
||||
@@ -42,26 +42,31 @@
|
||||
community-id %])
|
||||
:on-error #(log/error "failed to request to join community" community-id %)}]})
|
||||
|
||||
(defn request-to-join
|
||||
[{:keys [db]} [{:keys [community-id password]}]]
|
||||
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||
addresses-to-reveal []]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_generateJoiningCommunityRequestsForSigning"
|
||||
:params [pub-key community-id addresses-to-reveal]
|
||||
:on-success [:communities/sign-data community-id password]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]}))
|
||||
|
||||
;; Event to be called to request to join a community.
|
||||
;; This event will generate the data to be signed and then call the sign-data event.
|
||||
;; This is the only event that should be called from the UI.
|
||||
(rf/reg-event-fx :communities/request-to-join
|
||||
(fn [{:keys [db]} [{:keys [community-id password]}]]
|
||||
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||
addresses-to-reveal []]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_generateJoiningCommunityRequestsForSigning"
|
||||
:params [pub-key community-id addresses-to-reveal]
|
||||
:on-success [:communities/sign-data community-id password]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]})))
|
||||
(rf/reg-event-fx :communities/request-to-join request-to-join)
|
||||
|
||||
(rf/reg-event-fx :communities/sign-data
|
||||
(fn [_ [community-id password sign-params]]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_signData"
|
||||
:params [(map #(assoc % :password password) sign-params)]
|
||||
:on-success [:communities/request-to-join-with-signatures community-id]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]}))
|
||||
(defn sign-data
|
||||
[_ [community-id password sign-params]]
|
||||
(let [addresses-to-reveal (map :account sign-params)]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_signData"
|
||||
:params [(map #(assoc % :password password) sign-params)]
|
||||
:on-success [:communities/request-to-join-with-signatures community-id addresses-to-reveal]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :communities/sign-data sign-data)
|
||||
|
||||
(rf/reg-event-fx :communities/requested-to-join-error
|
||||
(fn [{:keys [db]} [community-id error]]
|
||||
@@ -71,11 +76,19 @@
|
||||
:event :communities/requested-to-join-error})
|
||||
{:db (assoc-in db [:password-authentication :error] error)}))
|
||||
|
||||
(rf/reg-event-fx :communities/request-to-join-with-signatures
|
||||
(fn [_ [community-id signatures]]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id :signatures signatures}]
|
||||
:js-response true
|
||||
:on-success [:communities/requested-to-join]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]}))
|
||||
(defn request-to-join-with-signatures
|
||||
[_ [community-id addresses-to-reveal signatures]]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id
|
||||
:signatures signatures
|
||||
:addressesToReveal addresses-to-reveal
|
||||
;; NOTE: At least one airdrop address is required.
|
||||
;; This is a temporary solution while the address
|
||||
;; selection feature is not implemented in mobile.
|
||||
:airdropAddress (first addresses-to-reveal)}]
|
||||
:js-response true
|
||||
:on-success [:communities/requested-to-join]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]})
|
||||
|
||||
(rf/reg-event-fx :communities/request-to-join-with-signatures request-to-join-with-signatures)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
(ns status-im2.contexts.communities.overview.events-test
|
||||
(:require [cljs.test :refer [deftest is]]
|
||||
[native-module.core :as native-module]
|
||||
[status-im2.contexts.communities.overview.events :as sut]))
|
||||
|
||||
(def password (native-module/sha3 "password123"))
|
||||
(def community-id "0x99")
|
||||
(def account-pub-key "0x1")
|
||||
|
||||
(deftest request-to-join-test
|
||||
(let [cofx {:db {:profile/profile {:public-key account-pub-key}}}
|
||||
expected {:fx [[:json-rpc/call
|
||||
[{:method "wakuext_generateJoiningCommunityRequestsForSigning"
|
||||
:params [account-pub-key community-id []]
|
||||
:on-success [:communities/sign-data community-id password]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]}]
|
||||
(is (= expected
|
||||
(sut/request-to-join cofx
|
||||
[{:community-id community-id
|
||||
:password password}])))))
|
||||
|
||||
(deftest sign-data-test
|
||||
(let [cofx {:db {}}
|
||||
sign-params [{:data "123" :account account-pub-key}
|
||||
{:data "456" :account "0x2"}]
|
||||
addresses-to-reveal [account-pub-key "0x2"]
|
||||
expected {:fx
|
||||
[[:json-rpc/call
|
||||
[{:method "wakuext_signData"
|
||||
:params [[{:data "123" :account account-pub-key :password password}
|
||||
{:data "456" :account "0x2" :password password}]]
|
||||
:on-success [:communities/request-to-join-with-signatures
|
||||
community-id addresses-to-reveal]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]}]
|
||||
(is (= expected
|
||||
(sut/sign-data cofx [community-id password sign-params])))))
|
||||
|
||||
(deftest request-to-join-with-signatures-test
|
||||
(let [cofx {:db {}}
|
||||
addresses-to-reveal [account-pub-key "0x2"]
|
||||
signatures ["11111" "222222"]
|
||||
expected {:fx [[:json-rpc/call
|
||||
[{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id
|
||||
:signatures signatures
|
||||
:addressesToReveal addresses-to-reveal
|
||||
:airdropAddress "0x1"}]
|
||||
:js-response true
|
||||
:on-success [:communities/requested-to-join]
|
||||
:on-error [:communities/requested-to-join-error
|
||||
community-id]}]]]}]
|
||||
(is (= expected
|
||||
(sut/request-to-join-with-signatures cofx [community-id addresses-to-reveal signatures])))))
|
||||
@@ -255,7 +255,7 @@
|
||||
(defn community-content
|
||||
[community]
|
||||
(rf/dispatch [:communities/check-all-community-channels-permissions (:id community)])
|
||||
(fn [{:keys [name description joined images tags color id] :as community}
|
||||
(fn [{:keys [name description joined images tags color id token-permissions] :as community}
|
||||
pending?
|
||||
{:keys [on-category-layout
|
||||
collapsed?
|
||||
@@ -273,12 +273,14 @@
|
||||
:last-item-style style/last-community-tag
|
||||
:container-style style/community-tag-container}])
|
||||
[join-community community pending?]]
|
||||
[channel-list-component
|
||||
{:on-category-layout on-category-layout
|
||||
:community-id id
|
||||
:community-color color
|
||||
:on-first-channel-height-changed on-first-channel-height-changed}
|
||||
(add-handlers-to-categorized-chats id chats-by-category joined)]])))
|
||||
(when (or (and (seq token-permissions) joined)
|
||||
(empty? token-permissions))
|
||||
[channel-list-component
|
||||
{:on-category-layout on-category-layout
|
||||
:community-id id
|
||||
:community-color color
|
||||
:on-first-channel-height-changed on-first-channel-height-changed}
|
||||
(add-handlers-to-categorized-chats id chats-by-category joined)])])))
|
||||
|
||||
(defn sticky-category-header
|
||||
[_]
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
(ns status-im2.contexts.onboarding.enable-biometrics.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im2.common.biometric.events :as biometric]
|
||||
[status-im2.common.parallax.view :as parallax]
|
||||
[status-im2.common.parallax.whitelist :as whitelist]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.common.standard-authentication.core :as standard-auth]
|
||||
[status-im2.contexts.onboarding.enable-biometrics.style :as style]
|
||||
[status-im2.navigation.state :as state]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
|
||||
(defn page-title
|
||||
[]
|
||||
@@ -21,22 +26,39 @@
|
||||
:description-accessibility-label :enable-biometrics-sub-title}])
|
||||
|
||||
(defn enable-biometrics-buttons
|
||||
[insets]
|
||||
[insets theme]
|
||||
(let [supported-biometric-type (rf/sub [:biometric/supported-type])
|
||||
bio-type-label (biometric/get-label-by-type supported-biometric-type)
|
||||
profile-color (:color (rf/sub [:onboarding-2/profile]))]
|
||||
profile-color (or (:color (rf/sub [:onboarding-2/profile]))
|
||||
(rf/sub [:profile/customization-color]))
|
||||
syncing-results? (= :syncing-results @state/root-id)]
|
||||
[rn/view {:style (style/buttons insets)}
|
||||
[quo/button
|
||||
{:accessibility-label :enable-biometrics-button
|
||||
:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])
|
||||
:icon-left :i/face-id
|
||||
:customization-color profile-color}
|
||||
(i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})]
|
||||
[standard-auth/button
|
||||
(merge
|
||||
{:size 40
|
||||
:accessibility-label :enable-biometrics-button
|
||||
:icon-left :i/face-id
|
||||
:customization-color profile-color
|
||||
:button-label (i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})}
|
||||
(if syncing-results?
|
||||
{:theme theme
|
||||
:blur? true
|
||||
:on-enter-password (fn [entered-password]
|
||||
(rf/dispatch
|
||||
[:onboarding-2/authenticate-enable-biometrics
|
||||
(security/safe-unmask-data
|
||||
entered-password)])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:auth-button-label (i18n/label :t/confirm)}
|
||||
{:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])}))]
|
||||
[quo/button
|
||||
{:accessibility-label :maybe-later-button
|
||||
:background :blur
|
||||
:type :grey
|
||||
:on-press #(rf/dispatch [:onboarding-2/create-account-and-login])
|
||||
:on-press #(rf/dispatch (if syncing-results?
|
||||
[:navigate-to-within-stack
|
||||
[:enable-notifications :enable-biometrics]]
|
||||
[:onboarding-2/create-account-and-login]))
|
||||
:container-style {:margin-top 12}}
|
||||
(i18n/label :t/maybe-later)]]))
|
||||
|
||||
@@ -55,12 +77,19 @@
|
||||
:style (style/page-illustration width)
|
||||
:source (resources/get-image :biometrics)}]))
|
||||
|
||||
(defn enable-biometrics
|
||||
[]
|
||||
(defn f-enable-biometrics
|
||||
[{:keys [theme]}]
|
||||
(let [insets (safe-area/get-insets)]
|
||||
[rn/view {:style (style/page-container insets)}
|
||||
[page-title]
|
||||
(if whitelist/whitelisted?
|
||||
[enable-biometrics-parallax]
|
||||
[enable-biometrics-simple])
|
||||
[enable-biometrics-buttons insets]]))
|
||||
[enable-biometrics-buttons insets theme]]))
|
||||
|
||||
|
||||
(defn- internale-enable-biometrics
|
||||
[params]
|
||||
[:f> f-enable-biometrics params])
|
||||
|
||||
(def view (quo.theme/with-theme internale-enable-biometrics))
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
[quo/page-nav
|
||||
{:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back-within-stack :new-to-status])}]
|
||||
:on-press #(rf/dispatch [:navigate-back-within-stack :enable-biometrics])}]
|
||||
[page-title]
|
||||
[rn/view {:style style/page-illustration}
|
||||
[quo/text
|
||||
|
||||
@@ -35,11 +35,30 @@
|
||||
{:biometric/authenticate {:on-success #(rf/dispatch [:onboarding-2/biometrics-done])
|
||||
:on-fail #(rf/dispatch [:onboarding-2/biometrics-fail %])}})
|
||||
|
||||
(rf/defn authenticate-enable-biometrics
|
||||
{:events [:onboarding-2/authenticate-enable-biometrics]}
|
||||
[{:keys [db]} password]
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding-2/profile :password] password)
|
||||
(assoc-in [:onboarding-2/profile :syncing?] true))
|
||||
:biometric/authenticate {:on-success #(rf/dispatch [:onboarding-2/biometrics-done])
|
||||
:on-fail #(rf/dispatch [:onboarding-2/biometrics-fail %])}})
|
||||
|
||||
(rf/defn navigate-to-enable-notifications
|
||||
{:events [:onboarding-2/navigate-to-enable-notifications]}
|
||||
[{:keys [db]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:db (dissoc db :onboarding-2/profile)
|
||||
:dispatch [:navigate-to-within-stack [:enable-notifications :enable-biometrics]]}))
|
||||
|
||||
(rf/defn biometrics-done
|
||||
{:events [:onboarding-2/biometrics-done]}
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:onboarding-2/profile :auth-method] constants/auth-method-biometric)
|
||||
:dispatch [:onboarding-2/create-account-and-login]})
|
||||
(let [syncing? (get-in db [:onboarding-2/profile :syncing?])]
|
||||
{:db (assoc-in db [:onboarding-2/profile :auth-method] constants/auth-method-biometric)
|
||||
:dispatch (if syncing?
|
||||
[:onboarding-2/finalize-setup]
|
||||
[:onboarding-2/create-account-and-login])}))
|
||||
|
||||
(rf/defn biometrics-fail
|
||||
{:events [:onboarding-2/biometrics-fail]}
|
||||
@@ -83,6 +102,14 @@
|
||||
[:navigate-to-within-stack [:enable-biometrics :new-to-status]]
|
||||
[:onboarding-2/create-account-and-login])}))
|
||||
|
||||
(rf/defn navigate-to-enable-biometrics
|
||||
{:events [:onboarding-2/navigate-to-enable-biometrics]}
|
||||
[{:keys [db]}]
|
||||
(let [supported-type (:biometric/supported-type db)]
|
||||
{:dispatch (if supported-type
|
||||
[:open-modal :enable-biometrics]
|
||||
[:open-modal :enable-notifications])}))
|
||||
|
||||
(rf/defn seed-phrase-entered
|
||||
{:events [:onboarding-2/seed-phrase-entered]}
|
||||
[_ seed-phrase on-error]
|
||||
@@ -120,6 +147,7 @@
|
||||
[{:keys [db]}]
|
||||
(let [masked-password (get-in db [:onboarding-2/profile :password])
|
||||
key-uid (get-in db [:profile/profile :key-uid])
|
||||
syncing? (get-in db [:onboarding-2/profile :syncing?])
|
||||
biometric-enabled? (= (get-in db [:onboarding-2/profile :auth-method])
|
||||
constants/auth-method-biometric)]
|
||||
(cond-> {:db (assoc db :onboarding-2/generated-keys? true)}
|
||||
@@ -127,7 +155,10 @@
|
||||
(assoc :keychain/save-password-and-auth-method
|
||||
{:key-uid key-uid
|
||||
:masked-password masked-password
|
||||
:on-success #(log/debug "successfully saved biometric")
|
||||
:on-success (fn []
|
||||
(if syncing?
|
||||
(rf/dispatch [:onboarding-2/navigate-to-enable-notifications])
|
||||
(log/error "successfully saved biometrics")))
|
||||
:on-error #(log/error "failed to save biometrics"
|
||||
{:key-uid key-uid
|
||||
:error %})}))))
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
{:on-press (fn []
|
||||
(when on-press
|
||||
(on-press))
|
||||
(rf/dispatch [:open-modal :enable-notifications]))
|
||||
(rf/dispatch [:onboarding-2/navigate-to-enable-biometrics]))
|
||||
:accessibility-label :continue-button
|
||||
:customization-color profile-color
|
||||
:container-style style/continue-button}
|
||||
|
||||
@@ -73,12 +73,12 @@
|
||||
(data-store.settings/rpc->settings settings)
|
||||
profile-overview (profile.rpc/rpc->profiles-overview account)]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc :chats/loading? true
|
||||
:networks/current-network current-network
|
||||
:networks/networks (merge networks config/default-networks-by-id)
|
||||
:profile/profile (merge profile-overview settings))
|
||||
(assoc-in [:wallet :ui :tokens-loading?] true))}
|
||||
{:db (assoc db
|
||||
:chats/loading? true
|
||||
:networks/current-network current-network
|
||||
:wallet/tokens-loading? true
|
||||
:networks/networks (merge networks config/default-networks-by-id)
|
||||
:profile/profile (merge profile-overview settings))}
|
||||
(notifications/load-preferences)
|
||||
(data-store.chats/fetch-chats-preview
|
||||
{:on-success
|
||||
|
||||
@@ -153,7 +153,6 @@
|
||||
[status-im2.contexts.quo-preview.tags.number-tag :as number-tag]
|
||||
[status-im2.contexts.quo-preview.tags.permission-tag :as permission-tag]
|
||||
[status-im2.contexts.quo-preview.tags.status-tags :as status-tags]
|
||||
[status-im2.contexts.quo-preview.tags.summary-tag :as summary-tag]
|
||||
[status-im2.contexts.quo-preview.tags.tag :as tag]
|
||||
[status-im2.contexts.quo-preview.tags.tags :as tags]
|
||||
[status-im2.contexts.quo-preview.tags.tiny-tag :as tiny-tag]
|
||||
@@ -434,8 +433,6 @@
|
||||
:component permission-tag/view}
|
||||
{:name :status-tags
|
||||
:component status-tags/view}
|
||||
{:name :summary-tag
|
||||
:component summary-tag/view}
|
||||
{:name :tag
|
||||
:component tag/view}
|
||||
{:name :tags
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
(ns status-im2.contexts.quo-preview.tags.summary-tag
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.resources :as quo.resources]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(defn data
|
||||
[type]
|
||||
(case type
|
||||
:token
|
||||
{:customization-color "#9999991A"
|
||||
:label "150 ETH"
|
||||
:image-source (quo.resources/get-token :eth)}
|
||||
:address
|
||||
{:label "0x39c...Bd2"}
|
||||
:user
|
||||
{:image-source (resources/mock-images :user-picture-male4)
|
||||
:customization-color :blue
|
||||
:label "Mark Libot"}
|
||||
:collectible
|
||||
{:label "Isekai #1"
|
||||
:image-source (resources/mock-images :collectible2)
|
||||
:customization-color :yellow}
|
||||
:network
|
||||
{:image-source (quo.resources/get-network :ethereum)
|
||||
:label "Mainnet"}
|
||||
:saved-address
|
||||
{:customization-color :flamingo
|
||||
:label "Peter Lambo"}
|
||||
:account
|
||||
{:label "Account"
|
||||
:emoji "🍿"
|
||||
:customization-color :purple}))
|
||||
|
||||
(def descriptor
|
||||
[{:key :type
|
||||
:type :select
|
||||
:options [{:value "Token"
|
||||
:key :token}
|
||||
{:value "Address"
|
||||
:key :address}
|
||||
{:value "User"
|
||||
:key :user}
|
||||
{:value "Collectible"
|
||||
:key :collectible}
|
||||
{:value "Network"
|
||||
:key :network}
|
||||
{:value "Saved address"
|
||||
:key :saved-address}
|
||||
{:value "Account"
|
||||
:key :account}]}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom
|
||||
(merge {:type :token}
|
||||
(data :token)))]
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor}
|
||||
[rn/view {:style {:align-items :center}}
|
||||
[quo/summary-tag (merge @state (data (:type @state)))]]])))
|
||||
@@ -8,7 +8,7 @@
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.qr-codes.view :as qr-codes]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.common.standard-authentication.standard-auth.view :as standard-auth]
|
||||
[status-im2.common.standard-authentication.core :as standard-auth]
|
||||
[status-im2.contexts.syncing.setup-syncing.style :as style]
|
||||
[status-im2.contexts.syncing.utils :as sync-utils]
|
||||
[utils.datetime :as datetime]
|
||||
@@ -119,7 +119,7 @@
|
||||
(i18n/label :t/copy-qr)]])
|
||||
(when-not (sync-utils/valid-connection-string? @code)
|
||||
[rn/view {:style style/standard-auth}
|
||||
[standard-auth/view
|
||||
[standard-auth/slide-button
|
||||
{:blur? true
|
||||
:size :size-40
|
||||
:track-text (i18n/label :t/slide-to-reveal-code)
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
(ns status-im2.contexts.wallet.common.utils
|
||||
(:require [clojure.string :as string]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.number]))
|
||||
[status-im2.constants :as constants]))
|
||||
|
||||
(defn get-first-name
|
||||
[full-name]
|
||||
(first (string/split full-name #" ")))
|
||||
|
||||
(defn get-balance-by-address
|
||||
[balances address]
|
||||
(->> balances
|
||||
(filter #(= (:address %) address))
|
||||
first
|
||||
:balance))
|
||||
|
||||
(defn get-account-by-address
|
||||
[accounts address]
|
||||
(some #(when (= (:address %) address) %) accounts))
|
||||
|
||||
(defn prettify-balance
|
||||
[balance]
|
||||
(str "$" (.toFixed (if (number? balance) balance 0) 2)))
|
||||
@@ -22,24 +32,3 @@
|
||||
[number-of-accounts]
|
||||
(let [path (get-derivation-path number-of-accounts)]
|
||||
(format-derivation-path path)))
|
||||
|
||||
(defn- calculate-raw-balance
|
||||
[raw-balance decimals]
|
||||
(if-let [n (utils.number/parse-int raw-balance nil)]
|
||||
(/ n (Math/pow 10 (utils.number/parse-int decimals)))
|
||||
0))
|
||||
|
||||
(defn- total-token-value-in-all-chains
|
||||
[{:keys [balances-per-chain decimals]}]
|
||||
(->> balances-per-chain
|
||||
(vals)
|
||||
(map #(calculate-raw-balance (:raw-balance %) decimals))
|
||||
(reduce +)))
|
||||
|
||||
(defn calculate-balance
|
||||
[tokens-in-account]
|
||||
(->> tokens-in-account
|
||||
(map (fn [token]
|
||||
(* (total-token-value-in-all-chains token)
|
||||
(-> token :market-values-per-currency :usd :price))))
|
||||
(reduce +)))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.standard-authentication.standard-auth.view :as standard-auth]
|
||||
[status-im2.common.standard-authentication.core :as standard-auth]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.emoji-picker.utils :as emoji-picker.utils]
|
||||
[status-im2.contexts.wallet.common.utils :as utils]
|
||||
@@ -114,7 +114,7 @@
|
||||
{:list-type :settings
|
||||
:label (i18n/label :t/origin)
|
||||
:data (get-keypair-data primary-name @derivation-path @account-color)}]
|
||||
[standard-auth/view
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-create-account)
|
||||
:customization-color @account-color
|
||||
|
||||
@@ -4,33 +4,29 @@
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.wallet.common.screen-base.create-or-edit-account.view
|
||||
:as create-or-edit-account]
|
||||
[status-im2.contexts.wallet.common.sheets.network-preferences.view
|
||||
:as network-preferences]
|
||||
[status-im2.contexts.wallet.common.screen-base.create-or-edit-account.view :as
|
||||
create-or-edit-account]
|
||||
[status-im2.contexts.wallet.common.sheets.network-preferences.view :as network-preferences]
|
||||
[status-im2.contexts.wallet.edit-account.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- show-save-account-toast
|
||||
[updated-key theme]
|
||||
(let [message (case updated-key
|
||||
:name :t/edit-wallet-account-name-updated-message
|
||||
:color :t/edit-wallet-account-colour-updated-message
|
||||
:emoji :t/edit-wallet-account-emoji-updated-message
|
||||
nil)]
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :edit-account
|
||||
:icon :i/correct
|
||||
:icon-color (colors/resolve-color :success theme)
|
||||
:text (i18n/label message)}])))
|
||||
|
||||
(defn- save-account
|
||||
[{:keys [account updated-key new-value theme]}]
|
||||
(let [edited-account-data (assoc account updated-key new-value)]
|
||||
[{:keys [theme type value account]}]
|
||||
(let [edited-account-data (assoc account type value)
|
||||
message (case type
|
||||
:name :t/edit-wallet-account-name-updated-message
|
||||
:color :t/edit-wallet-account-colour-updated-message
|
||||
:emoji :t/edit-wallet-account-emoji-updated-message
|
||||
nil)
|
||||
callback #(rf/dispatch [:toasts/upsert
|
||||
{:id :edit-account
|
||||
:icon :i/correct
|
||||
:icon-color (colors/resolve-color :success theme)
|
||||
:text (i18n/label message)}])]
|
||||
(rf/dispatch [:wallet/save-account
|
||||
{:account edited-account-data
|
||||
:on-success #(show-save-account-toast updated-key theme)}])))
|
||||
{:account edited-account-data
|
||||
:callback callback}])))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [theme]}]
|
||||
@@ -38,22 +34,22 @@
|
||||
show-confirm-button? (reagent/atom false)
|
||||
on-change-color (fn [edited-color {:keys [color] :as account}]
|
||||
(when (not= edited-color color)
|
||||
(save-account {:account account
|
||||
:updated-key :color
|
||||
:new-value edited-color
|
||||
:theme theme})))
|
||||
(save-account {:account account
|
||||
:type :color
|
||||
:value edited-color
|
||||
:theme theme})))
|
||||
on-change-emoji (fn [edited-emoji {:keys [emoji] :as account}]
|
||||
(when (not= edited-emoji emoji)
|
||||
(save-account {:account account
|
||||
:updated-key :emoji
|
||||
:new-value edited-emoji
|
||||
:theme theme})))
|
||||
(save-account {:account account
|
||||
:type :emoji
|
||||
:value edited-emoji
|
||||
:theme theme})))
|
||||
on-confirm-name (fn [account]
|
||||
(rn/dismiss-keyboard!)
|
||||
(save-account {:account account
|
||||
:updated-key :name
|
||||
:new-value @edited-account-name
|
||||
:theme theme}))]
|
||||
(save-account {:account account
|
||||
:type :name
|
||||
:value @edited-account-name
|
||||
:theme theme}))]
|
||||
(fn []
|
||||
(let [{:keys [name emoji address color]
|
||||
:as account} (rf/sub [:wallet/current-viewing-account])
|
||||
@@ -86,18 +82,17 @@
|
||||
:right-icon :i/advanced
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (fn []
|
||||
[quo/address-text
|
||||
{:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}
|
||||
{:network-name :arbitrum :short-name "arb1"}]
|
||||
:address address
|
||||
:format :long}])
|
||||
:custom-subtitle (fn [] [quo/address-text
|
||||
{:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}
|
||||
{:network-name :arbitrum :short-name "arb1"}]
|
||||
:address address
|
||||
:format :long}])
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[network-preferences/view
|
||||
{:on-save #(js/alert "calling on save")}])}]))
|
||||
{:content (fn [] [network-preferences/view
|
||||
{:on-save #(js/alert
|
||||
"calling on save")}])}]))
|
||||
:container-style style/data-item}]]))))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.number]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as types]))
|
||||
@@ -41,8 +40,7 @@
|
||||
{:db (update db :wallet dissoc :current-viewing-account-address)
|
||||
:fx [[:dispatch [:navigate-back]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-accounts-success
|
||||
(rf/reg-event-fx :wallet/get-accounts-success
|
||||
(fn [{:keys [db]} [accounts]]
|
||||
(let [wallet-db (get db :wallet)
|
||||
new-account? (:new-account? wallet-db)
|
||||
@@ -63,8 +61,7 @@
|
||||
{:dispatch [:wallet/navigate-to-account navigate-to-account]
|
||||
:ms 300}]])))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-accounts
|
||||
(rf/reg-event-fx :wallet/get-accounts
|
||||
(fn [_]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "accounts_getAccounts"
|
||||
@@ -75,54 +72,35 @@
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/save-account
|
||||
(fn [_ [{:keys [account on-success]}]]
|
||||
(fn [_ [{:keys [account callback]}]]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "accounts_saveAccount"
|
||||
:params [(data-store/<-account account)]
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:wallet/get-accounts])
|
||||
(when (fn? on-success)
|
||||
(on-success)))
|
||||
(when (fn? callback)
|
||||
(callback)))
|
||||
:on-error #(log/info "failed to save account "
|
||||
{:error %
|
||||
:event :wallet/save-account})}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-wallet-token
|
||||
(rf/reg-event-fx :wallet/get-wallet-token
|
||||
(fn [{:keys [db]}]
|
||||
(let [addresses (->> (get-in db [:wallet :accounts])
|
||||
vals
|
||||
(map :address))]
|
||||
(let [addresses (map :address (vals (get-in db [:wallet :accounts])))]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_getWalletToken"
|
||||
:params [addresses]
|
||||
:on-success [:wallet/store-wallet-token]
|
||||
:on-success [:wallet/get-wallet-token-success]
|
||||
:on-error #(log/info "failed to get wallet token "
|
||||
{:error %
|
||||
:event :wallet/get-wallet-token
|
||||
:params addresses})}]]]})))
|
||||
|
||||
(defn- fix-chain-id-keys
|
||||
[token]
|
||||
(update token :balances-per-chain update-keys (comp utils.number/parse-int name)))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/store-wallet-token
|
||||
(fn [{:keys [db]} [raw-tokens-data]]
|
||||
(let [tokens (-> raw-tokens-data
|
||||
(update-keys name)
|
||||
(update-vals #(cske/transform-keys csk/->kebab-case %))
|
||||
(update-vals #(mapv fix-chain-id-keys %)))
|
||||
add-tokens (fn [stored-accounts tokens-per-account]
|
||||
(reduce-kv (fn [accounts address tokens-data]
|
||||
(if (accounts address)
|
||||
(update accounts address assoc :tokens tokens-data)
|
||||
accounts))
|
||||
stored-accounts
|
||||
tokens-per-account))]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :accounts] add-tokens tokens)
|
||||
(assoc-in [:wallet :ui :tokens-loading?] false))})))
|
||||
(rf/reg-event-fx :wallet/get-wallet-token-success
|
||||
(fn [{:keys [db]} [tokens]]
|
||||
{:db (assoc db
|
||||
:wallet/tokens tokens
|
||||
:wallet/tokens-loading? false)}))
|
||||
|
||||
(rf/defn scan-address-success
|
||||
{:events [:wallet/scan-address-success]}
|
||||
@@ -144,8 +122,7 @@
|
||||
:on-success on-success
|
||||
:on-error #(log/info "failed to derive address " %)}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/add-account
|
||||
(rf/reg-event-fx :wallet/add-account
|
||||
(fn [{:keys [db]} [password {:keys [emoji account-name color]} {:keys [public-key address path]}]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
sha3-pwd (native-module/sha3 (security/safe-unmask-data password))
|
||||
@@ -169,12 +146,11 @@
|
||||
:on-success [:wallet/get-accounts]
|
||||
:on-error #(log/info "failed to create account " %)}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/derive-address-and-add-account
|
||||
(rf/reg-event-fx :wallet/derive-address-and-add-account
|
||||
(fn [_ [password account-details]]
|
||||
(let [on-success (fn [derived-address-details]
|
||||
(let [on-success (fn [derived-adress-details]
|
||||
(rf/dispatch [:wallet/add-account password account-details
|
||||
(first derived-address-details)]))]
|
||||
(first derived-adress-details)]))]
|
||||
{:fx [[:dispatch [:wallet/create-derived-addresses password account-details on-success]]]})))
|
||||
|
||||
(rf/defn get-ethereum-chains
|
||||
@@ -223,8 +199,7 @@
|
||||
|
||||
(rf/reg-event-fx :wallet/clear-stored-collectibles clear-stored-collectibles)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/request-collectibles
|
||||
(rf/reg-event-fx :wallet/request-collectibles
|
||||
(fn [{:keys [db]} [{:keys [start-at-index new-request?]}]]
|
||||
(let [request-id 0
|
||||
collectibles-filter nil
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
[status-im2.contexts.wallet.common.activity-tab.view :as activity]
|
||||
[status-im2.contexts.wallet.common.collectibles-tab.view :as collectibles]
|
||||
[status-im2.contexts.wallet.common.temp :as temp]
|
||||
[status-im2.contexts.wallet.common.utils :as utils]
|
||||
[status-im2.contexts.wallet.home.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -27,9 +28,9 @@
|
||||
:on-press #(rf/dispatch [:navigate-to :add-address-to-watch])
|
||||
:add-divider? true}]]])
|
||||
|
||||
(defn- new-account-card-data
|
||||
[]
|
||||
{:customization-color (rf/sub [:profile/customization-color])
|
||||
(defn- add-account-placeholder
|
||||
[color]
|
||||
{:customization-color color
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet {:content new-account}])
|
||||
:type :add-account})
|
||||
|
||||
@@ -38,6 +39,21 @@
|
||||
{:id :collectibles :label (i18n/label :t/collectibles) :accessibility-label :collectibles-tab}
|
||||
{:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab}])
|
||||
|
||||
(defn account-cards
|
||||
[{:keys [accounts loading? balances profile-color]}]
|
||||
(let [accounts-with-balances
|
||||
(mapv
|
||||
(fn [{:keys [color address] :as account}]
|
||||
(assoc account
|
||||
:customization-color color
|
||||
:type :empty
|
||||
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
|
||||
:loading? loading?
|
||||
:balance (utils/prettify-balance
|
||||
(utils/get-balance-by-address balances address))))
|
||||
accounts)]
|
||||
(conj accounts-with-balances (add-account-placeholder profile-color))))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(rf/dispatch [:wallet/request-collectibles
|
||||
@@ -46,10 +62,14 @@
|
||||
(let [top (safe-area/get-top)
|
||||
selected-tab (reagent/atom (:id (first tabs-data)))]
|
||||
(fn []
|
||||
(let [networks (rf/sub [:wallet/network-details])
|
||||
account-cards-data (rf/sub [:wallet/account-cards-data])
|
||||
cards (conj account-cards-data (new-account-card-data))]
|
||||
[rn/view {:style {:margin-top top :flex 1}}
|
||||
(let [accounts (rf/sub [:wallet/accounts])
|
||||
loading? (rf/sub [:wallet/tokens-loading?])
|
||||
balances (rf/sub [:wallet/balances])
|
||||
profile-color (rf/sub [:profile/customization-color])
|
||||
networks (rf/sub [:wallet/network-details])]
|
||||
[rn/view
|
||||
{:style {:margin-top top
|
||||
:flex 1}}
|
||||
[common.top-nav/view]
|
||||
[rn/view {:style style/overview-container}
|
||||
[quo/wallet-overview (temp/wallet-overview-state networks)]]
|
||||
@@ -60,7 +80,10 @@
|
||||
[rn/flat-list
|
||||
{:style style/accounts-list
|
||||
:content-container-style style/accounts-list-container
|
||||
:data cards
|
||||
:data (account-cards {:accounts accounts
|
||||
:loading? loading?
|
||||
:balances balances
|
||||
:profile-color profile-color})
|
||||
:horizontal true
|
||||
:separator [rn/view {:style {:width 12}}]
|
||||
:render-fn quo/account-card
|
||||
|
||||
@@ -161,11 +161,15 @@
|
||||
:component create-password/create-password}
|
||||
|
||||
{:name :enable-biometrics
|
||||
:options {:theme :dark
|
||||
:layout options/onboarding-transparent-layout
|
||||
:animations transitions/push-animations-for-transparent-background
|
||||
:popGesture false}
|
||||
:component enable-biometrics/enable-biometrics}
|
||||
:options {:theme :dark
|
||||
:layout options/onboarding-transparent-layout
|
||||
:animations (merge transitions/new-to-status-modal-animations
|
||||
transitions/push-animations-for-transparent-background)
|
||||
:popGesture false
|
||||
:modalPresentationStyle :overCurrentContext
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
:popStackOnPress false}}
|
||||
:component enable-biometrics/view}
|
||||
|
||||
{:name :generating-keys
|
||||
:options {:theme :dark
|
||||
|
||||
@@ -63,6 +63,25 @@
|
||||
(fn [{:keys [public-key]}]
|
||||
public-key))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:profile/webview-debug
|
||||
:<- [:profile/profile]
|
||||
(fn [{:keys [webview-debug]}]
|
||||
webview-debug))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:profile/light-client-enabled?
|
||||
:<- [:profile/profile]
|
||||
(fn [profile]
|
||||
(get-in profile [:wakuv2-config :LightClient])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:profile/test-networks-enabled?
|
||||
:<- [:profile/profile]
|
||||
(fn [profile]
|
||||
(:test-networks-enabled? profile)))
|
||||
|
||||
|
||||
(re-frame/reg-sub
|
||||
:multiaccount/contact
|
||||
:<- [:profile/profile]
|
||||
@@ -112,12 +131,6 @@
|
||||
(fn [multiaccount]
|
||||
(get multiaccount :log-level)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:waku/bloom-filter-mode
|
||||
:<- [:profile/profile]
|
||||
(fn [multiaccount]
|
||||
(boolean (get multiaccount :waku-bloom-filter-mode))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:waku/v2-flag
|
||||
:<- [:fleets/current-fleet]
|
||||
|
||||
@@ -145,6 +145,10 @@
|
||||
(reg-root-key-sub :communities/selected-tab :communities/selected-tab)
|
||||
(reg-root-key-sub :contract-communities :contract-communities)
|
||||
|
||||
;;wallet
|
||||
(reg-root-key-sub :wallet/tokens :wallet/tokens)
|
||||
(reg-root-key-sub :wallet/tokens-loading? :wallet/tokens-loading?)
|
||||
|
||||
;;activity center
|
||||
(reg-root-key-sub :activity-center :activity-center)
|
||||
|
||||
|
||||
@@ -1,19 +1,36 @@
|
||||
(ns status-im2.subs.wallet.wallet
|
||||
(:require [re-frame.core :as rf]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im2.contexts.wallet.common.utils :as utils]
|
||||
[utils.number]))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/ui
|
||||
:<- [:wallet]
|
||||
:-> :ui)
|
||||
(defn- calculate-raw-balance
|
||||
[raw-balance decimals]
|
||||
(if-let [n (utils.number/parse-int raw-balance nil)]
|
||||
(/ n (Math/pow 10 (utils.number/parse-int decimals)))
|
||||
0))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tokens-loading?
|
||||
:<- [:wallet/ui]
|
||||
:-> :tokens-loading?)
|
||||
(defn- total-per-token
|
||||
[item]
|
||||
(reduce (fn [ac balances]
|
||||
(+ (calculate-raw-balance (:rawBalance balances)
|
||||
(:decimals item))
|
||||
ac))
|
||||
0
|
||||
(vals (:balancesPerChain item))))
|
||||
|
||||
(rf/reg-sub
|
||||
(defn- calculate-balance
|
||||
[address tokens]
|
||||
(let [token (get tokens (keyword address))
|
||||
result (reduce
|
||||
(fn [acc item]
|
||||
(let [total-values (* (total-per-token item)
|
||||
(get-in item [:marketValuesPerCurrency :USD :price]))]
|
||||
(+ acc total-values)))
|
||||
0
|
||||
token)]
|
||||
result))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/accounts
|
||||
:<- [:wallet]
|
||||
:-> #(->> %
|
||||
@@ -21,33 +38,20 @@
|
||||
vals
|
||||
(sort-by :position)))
|
||||
|
||||
(rf/reg-sub
|
||||
(re-frame/reg-sub
|
||||
:wallet/balances
|
||||
:<- [:wallet/accounts]
|
||||
(fn [accounts]
|
||||
(zipmap (map :address accounts)
|
||||
(map #(-> % :tokens utils/calculate-balance) accounts))))
|
||||
:<- [:wallet/tokens]
|
||||
(fn [[accounts tokens]]
|
||||
(for [{:keys [address]} accounts]
|
||||
{:address address
|
||||
:balance (calculate-balance address tokens)})))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/account-cards-data
|
||||
:<- [:wallet/accounts]
|
||||
:<- [:wallet/balances]
|
||||
:<- [:wallet/tokens-loading?]
|
||||
(fn [[accounts balances tokens-loading?]]
|
||||
(mapv (fn [{:keys [color address] :as account}]
|
||||
(assoc account
|
||||
:customization-color color
|
||||
:type :empty
|
||||
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
|
||||
:loading? tokens-loading?
|
||||
:balance (utils/prettify-balance (get balances address))))
|
||||
accounts)))
|
||||
|
||||
(rf/reg-sub
|
||||
(re-frame/reg-sub
|
||||
:wallet/current-viewing-account
|
||||
:<- [:wallet]
|
||||
:<- [:wallet/balances]
|
||||
(fn [[{:keys [current-viewing-account-address] :as wallet} balances]]
|
||||
(-> wallet
|
||||
(get-in [:accounts current-viewing-account-address])
|
||||
(assoc :balance (get balances current-viewing-account-address)))))
|
||||
(assoc :balance (utils/get-balance-by-address balances current-viewing-account-address)))))
|
||||
|
||||
@@ -8,35 +8,43 @@
|
||||
(use-fixtures :each
|
||||
{:before #(reset! rf-db/app-db {})})
|
||||
|
||||
(def tokens-0x1
|
||||
[{:decimals 1
|
||||
:symbol "ETH"
|
||||
:name "Ether"
|
||||
:balances-per-chain {1 {:raw-balance "20" :has-error false}
|
||||
2 {:raw-balance "10" :has-error false}}
|
||||
:market-values-per-currency {:usd {:price 1000}}}
|
||||
{:decimals 2
|
||||
:symbol "DAI"
|
||||
:name "Dai Stablecoin"
|
||||
:balances-per-chain {1 {:raw-balance "100" :has-error false}
|
||||
2 {:raw-balance "150" :has-error false}}
|
||||
:market-values-per-currency {:usd {:price 100}}}])
|
||||
|
||||
(def tokens-0x2
|
||||
[{:decimals 3
|
||||
:symbol "ETH"
|
||||
:name "Ether"
|
||||
:balances-per-chain {1 {:raw-balance "2500" :has-error false}
|
||||
2 {:raw-balance "3000" :has-error false}
|
||||
3 {:raw-balance "<nil>" :has-error false}}
|
||||
:market-values-per-currency {:usd {:price 200}}}
|
||||
{:decimals 10
|
||||
:symbol "DAI"
|
||||
:name "Dai Stablecoin"
|
||||
:balances-per-chain {1 {:raw-balance "10000000000" :has-error false}
|
||||
2 {:raw-balance "0" :has-error false}
|
||||
3 {:raw-balance "<nil>" :has-error false}}
|
||||
:market-values-per-currency {:usd {:price 1000}}}])
|
||||
(def tokens
|
||||
{:0x1 [{:decimals 1
|
||||
:symbol "ETH"
|
||||
:name "Ether"
|
||||
:balancesPerChain {:1 {:rawBalance "20"
|
||||
:hasError false}
|
||||
:2 {:rawBalance "10"
|
||||
:hasError false}}
|
||||
:marketValuesPerCurrency {:USD {:price 1000}}} ;; total should be 3000
|
||||
{:decimals 2
|
||||
:symbol "DAI"
|
||||
:name "Dai Stablecoin"
|
||||
:balancesPerChain {:1 {:rawBalance "100"
|
||||
:hasError false}
|
||||
:2 {:rawBalance "150"
|
||||
:hasError false}}
|
||||
:marketValuesPerCurrency {:USD {:price 100}}}] ;; total should be 250
|
||||
:0x2 [{:decimals 3
|
||||
:symbol "ETH"
|
||||
:name "Ether"
|
||||
:balancesPerChain {:1 {:rawBalance "2500"
|
||||
:hasError false}
|
||||
:2 {:rawBalance "3000"
|
||||
:hasError false}
|
||||
:3 {:rawBalance "<nil>"
|
||||
:hasError false}}
|
||||
:marketValuesPerCurrency {:USD {:price 200}}} ;; total should be 1100
|
||||
{:decimals 10
|
||||
:symbol "DAI"
|
||||
:name "Dai Stablecoin"
|
||||
:balancesPerChain {:1 {:rawBalance "10000000000"
|
||||
:hasError false}
|
||||
:2 {:rawBalance "0"
|
||||
:hasError false}
|
||||
:3 {:rawBalance "<nil>"
|
||||
:hasError false}}
|
||||
:marketValuesPerCurrency {:USD {:price 1000}}}]}) ;; total should be 1000
|
||||
|
||||
(def accounts
|
||||
{"0x1" {:path "m/44'/60'/0'/0/0"
|
||||
@@ -57,8 +65,7 @@
|
||||
:operable "fully"
|
||||
:mixedcase-address "0x7bcDfc75c431"
|
||||
:public-key "0x04371e2d9d66b82f056bc128064"
|
||||
:removed false
|
||||
:tokens tokens-0x1}
|
||||
:removed false}
|
||||
"0x2" {:path "m/44'/60'/0'/0/1"
|
||||
:emoji "💎"
|
||||
:key-uid "0x2f5ea39"
|
||||
@@ -77,63 +84,66 @@
|
||||
:operable "fully"
|
||||
:mixedcase-address "0x7bcDfc75c431"
|
||||
:public-key "0x04371e2d9d66b82f056bc128064"
|
||||
:removed false
|
||||
:tokens tokens-0x2}})
|
||||
:removed false}})
|
||||
|
||||
(h/deftest-sub :wallet/balances
|
||||
[sub-name]
|
||||
(testing "a map: address->balance"
|
||||
(swap! rf-db/app-db #(assoc-in % [:wallet :accounts] accounts))
|
||||
|
||||
(is (= {"0x1" 3250 "0x2" 2100}
|
||||
(testing "returns seq of maps containing :address and :balance"
|
||||
(swap! rf-db/app-db #(-> %
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc :wallet/tokens tokens)))
|
||||
(is (= `({:address "0x1"
|
||||
:balance 3250}
|
||||
{:address "0x2"
|
||||
:balance 2100})
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
(h/deftest-sub :wallet/accounts
|
||||
[sub-name]
|
||||
(testing "returns all accounts without balance"
|
||||
(swap! rf-db/app-db #(assoc-in % [:wallet :accounts] accounts))
|
||||
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc :wallet/tokens tokens)))
|
||||
(is
|
||||
(= (list {:path "m/44'/60'/0'/0/0"
|
||||
:emoji "😃"
|
||||
:key-uid "0x2f5ea39"
|
||||
:address "0x1"
|
||||
:wallet false
|
||||
:name "Account One"
|
||||
:type :generated
|
||||
:chat false
|
||||
:test-preferred-chain-ids #{5 420 421613}
|
||||
:color :blue
|
||||
:hidden false
|
||||
:prod-preferred-chain-ids #{1 10 42161}
|
||||
:position 0
|
||||
:clock 1698945829328
|
||||
:created-at 1698928839000
|
||||
:operable "fully"
|
||||
:mixedcase-address "0x7bcDfc75c431"
|
||||
:public-key "0x04371e2d9d66b82f056bc128064"
|
||||
:removed false
|
||||
:tokens tokens-0x1}
|
||||
{:path "m/44'/60'/0'/0/1"
|
||||
:emoji "💎"
|
||||
:key-uid "0x2f5ea39"
|
||||
:address "0x2"
|
||||
:wallet false
|
||||
:name "Account Two"
|
||||
:type :generated
|
||||
:chat false
|
||||
:test-preferred-chain-ids #{5 420 421613}
|
||||
:color :purple
|
||||
:hidden false
|
||||
:prod-preferred-chain-ids #{1 10 42161}
|
||||
:position 1
|
||||
:clock 1698945829328
|
||||
:created-at 1698928839000
|
||||
:operable "fully"
|
||||
:mixedcase-address "0x7bcDfc75c431"
|
||||
:public-key "0x04371e2d9d66b82f056bc128064"
|
||||
:removed false
|
||||
:tokens tokens-0x2})
|
||||
(= `({:path "m/44'/60'/0'/0/0"
|
||||
:emoji "😃"
|
||||
:key-uid "0x2f5ea39"
|
||||
:address "0x1"
|
||||
:wallet false
|
||||
:name "Account One"
|
||||
:type :generated
|
||||
:chat false
|
||||
:test-preferred-chain-ids #{5 420 421613}
|
||||
:color :blue
|
||||
:hidden false
|
||||
:prod-preferred-chain-ids #{1 10 42161}
|
||||
:position 0
|
||||
:clock 1698945829328
|
||||
:created-at 1698928839000
|
||||
:operable "fully"
|
||||
:mixedcase-address "0x7bcDfc75c431"
|
||||
:public-key "0x04371e2d9d66b82f056bc128064"
|
||||
:removed false}
|
||||
{:path "m/44'/60'/0'/0/1"
|
||||
:emoji "💎"
|
||||
:key-uid "0x2f5ea39"
|
||||
:address "0x2"
|
||||
:wallet false
|
||||
:name "Account Two"
|
||||
:type :generated
|
||||
:chat false
|
||||
:test-preferred-chain-ids #{5 420 421613}
|
||||
:color :purple
|
||||
:hidden false
|
||||
:prod-preferred-chain-ids #{1 10 42161}
|
||||
:position 1
|
||||
:clock 1698945829328
|
||||
:created-at 1698928839000
|
||||
:operable "fully"
|
||||
:mixedcase-address "0x7bcDfc75c431"
|
||||
:public-key "0x04371e2d9d66b82f056bc128064"
|
||||
:removed false})
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
(h/deftest-sub :wallet/current-viewing-account
|
||||
@@ -142,8 +152,8 @@
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc-in [:wallet :current-viewing-account-address] "0x1")))
|
||||
|
||||
(assoc-in [:wallet :current-viewing-account-address] "0x1")
|
||||
(assoc :wallet/tokens tokens)))
|
||||
(is
|
||||
(= {:path "m/44'/60'/0'/0/0"
|
||||
:emoji "😃"
|
||||
@@ -164,6 +174,5 @@
|
||||
:mixedcase-address "0x7bcDfc75c431"
|
||||
:public-key "0x04371e2d9d66b82f056bc128064"
|
||||
:removed false
|
||||
:balance 3250
|
||||
:tokens tokens-0x1}
|
||||
:balance 3250}
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.171.11",
|
||||
"commit-sha1": "8a4c2d8d2f17117aa0a00338e83b0f753ebf1328",
|
||||
"src-sha256": "160qnl9dsl1ypvqg9w6z8wps4fvgq3qxi16piymhrlzgssdwkz8h"
|
||||
"version": "test-shard-test",
|
||||
"commit-sha1": "1a74a963384ec9598b6c6ed504cccdebd0a521f0",
|
||||
"src-sha256": "0cbbqwjshq1m4z3mcrw7iyzv16xyp7ffpnbpfwx869mbhcnir0vm"
|
||||
}
|
||||
|
||||
@@ -2372,6 +2372,7 @@
|
||||
"edit-derivation-path": "Edit derivation path",
|
||||
"path-format": "Path format",
|
||||
"reset": "Reset",
|
||||
"light-client-enabled": "Light client",
|
||||
"reveal-address": "Reveal address",
|
||||
"derive-addresses": "Derive addresses",
|
||||
"sign transactions": "sign transactions",
|
||||
|
||||
Reference in New Issue
Block a user