Compare commits

..
Author SHA1 Message Date
Andrea Maria Piana a99526cae4 fix statsugo version 2023-12-22 09:44:42 +00:00
Andrea Maria Piana 312683ec3b linting
https://github.com/status-im/status-go/compare/1adcf02f...52180f9a
2023-12-20 22:17:23 +00:00
Andrea Maria Piana 95e8cf44b2 fix kondo 2023-12-20 17:17:33 +00:00
Andrea Maria Piana fc18880178 Add fetch messages behind a toggle & some advanced settings
This PR does a few things:

1) Add fetch messages implementation on any kind of chat. It's behind a
   toggle (on by default) as design is still unsure whether we want it,
   but it's very useful for debugging.
2) Allow setting light client from mobile

It also partially remove node config management from the clojure part,
as it's better if that's not explicitly managed by clients.
Some parts are still relying on it but they are not functional
(keycard), while others are still using it and will need to be updated
eventually (syncing), in order to get rid completely of node config.

Sets fleet to shards.test

https://github.com/status-im/status-go/compare/90c31afe...1adcf02f
2023-12-20 17:16:59 +00:00
Andrea Maria Piana 285c7c40ea Use same branch as desktop 2023-12-20 15:24:56 +00:00
Vitaly Vlasov 5437a984a8 Resend messages fix
https://github.com/status-im/status-go/compare/8206ffc7...36dfa4f4
2023-12-01 12:08:51 +00:00
Siddarth Kumar a9e13f5aff don't restrict diawi upload for iOS release builds (#18016)
This commit removes the restriction of uploading iOS release builds to Diawi

Its helpful to have the status app uploaded to Diawi to test release builds on our iPhones.

The installer is very straightforward and makes life easier when we want to try out release builds.
2023-11-30 17:27:34 +05:30
alwx cdf5fe292f Detect image dimensions correctly 2023-11-23 09:29:39 +00:00
Andrea Maria Piana 70f0ba7784 Update status-go 2023-11-23 09:29:37 +00:00
John Ngei f03671097b enable biometric when user signs in with syncing (#17627) 2023-11-17 15:23:36 +00:00
frank 1db63a9fa1 local pair: check netIPs if empty before find server cert 2023-11-17 11:26:54 +00:00
Lungu CristianandIbrkhalil cd92b41214 Composer collapsing when editing canceled/done (#17785)
* fix: composer height when entering and canceling edit

* fix: blur the composer input when canceling edit

* fix: focusing animation and composer height after blur

* fix: input height when canceling edit while unfocused

* ref: removed arbitrary keyboard check

* fix: moved edit-mentions logic to use-edit to fix unresolved mention

* fix: composer edit should put the cursor at the end

* fix: (potentially) fixing the mention not resolved during edit

* fix: emoji-kb handler changing the height when default kb appears

* Fix text content when editing and reentering chat

* prevent composer when focusing on opening chat with edit/reply

* clean

* Clauxx comments

* Apply for reply

* Lintil soup = yummy

* refactor variable name

* Extract the focusing logic from the data setting logic

* Edge case

* fix: composer mention key & edit re-enter issues

* fix: reply cancel input blur and smooth reply focus

---------

Co-authored-by: Ibrkhalil <vampirekid017@gmail.com>
2023-11-17 11:14:23 +00:00
Andrea Maria Piana 56f7206da7 Restore shards 2023-11-16 19:43:29 +00:00
Andrea Maria Piana eb5de3506a Revert changes in sharded keys 2023-11-16 19:11:20 +00:00
flexsurfer 22005f916e [#17854] [IOS] The tutorial video animation keeps playing after openi… (#17915)
(cherry picked from commit 7153e4da48)
2023-11-16 12:36:13 +01:00
Flavio Fraschetti ff50aacb3a Hide channel list at token-gated communities overview (#17901)
This commit hides the categorized channel list for token-gated communities overview.
2023-11-16 10:57:54 +00:00
Icaro Motta 91300b9ff8 Fix: unable to join token-gated communities (#17894)
Fixes the bug by explicitly passing all available addresses to be revealed
to wakuext_requestToJoinCommunity and picking up the first available address
as the airdrop address. This is a temporary solution while we work on the
feature to allow users to choose which addresses to expose.

Fixes https://github.com/status-im/status-mobile/issues/17861

*Areas that may be impacted*: join community flows.

    ----------------------------------------------------------------------
    Community "Request to join" option is enabled.
    User holds more than X ETH.
    Anyone who holds <X> ETH is allowed to Become member in <COMMUNITY>.
    
    Expected: request to join is received by desktop client and accepted,
    mobile user joins the community.
    ----------------------------------------------------------------------
    
    ----------------------------------------------------------------------
    Community "Request to join" option is enabled.
    User holds less than X ETH.
    Anyone who holds <X> ETH is allowed to View and post in <CHANNEL>.
    
    Expected: request to join is received by desktop client and accepted, mobile
    user joins the community, but can't post in <CHANNEL>.
    ----------------------------------------------------------------------
    
    ----------------------------------------------------------------------
    Community "Request to join" option is enabled.
    No token permissions.
    
    Expected: request to join is received by desktop client and accepted,
    mobile user joins the community.
    ----------------------------------------------------------------------
2023-11-15 06:46:55 -03:00
Andrea Maria Piana d93b20242a Point to shared release branch 2023-11-14 10:54:02 +00:00
Andrea Maria Piana 0a43e5c97a Bump release to 1.26.0 2023-11-14 10:52:00 +00:00
71 changed files with 760 additions and 1011 deletions
+2
View File
@@ -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?])]}}}
+5 -6
View File
@@ -311,14 +311,13 @@ endef
lint: export TARGET := clojure
lint: export CLJ_LINTER_PRINT_WARNINGS ?= false
lint: ##@test Run code style checks
@sh scripts/lint/re-frame-in-quo-components.sh && \
sh scripts/lint/direct-require-component-outside-quo.sh && \
sh scripts/lint/require-i18n-resource-first.sh && \
@sh scripts/lint-re-frame-in-quo-components.sh && \
sh scripts/lint-direct-require-component-outside-quo.sh && \
clj-kondo --config .clj-kondo/config.edn --cache false --fail-level error --lint src $(if $(filter $(CLJ_LINTER_PRINT_WARNINGS),true),,| grep -v ': warning: ') && \
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
scripts/lint/translations.clj && \
scripts/lint_translations.clj && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
sh scripts/lint/trailing-newline.sh && \
sh scripts/lint-trailing-newline.sh && \
node_modules/.bin/prettier --write .
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
@@ -328,7 +327,7 @@ lint-fix: ##@test Run code style checks and fix issues
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
clojure-lsp --ns-exclude-regex ".*/src/status_im2/core\.cljs$$" clean-ns && \
sh scripts/lint/trailing-newline.sh --fix && \
sh scripts/lint-trailing-newline.sh --fix && \
node_modules/.bin/prettier --write .
shadow-server: export TARGET := clojure
+1 -1
View File
@@ -1 +1 @@
1.25.0
1.26.0
-1
View File
@@ -77,7 +77,6 @@ pipeline {
}
}
stage('Upload') {
when { expression { !utils.isReleaseBuild() } }
steps { script {
env.DIAWI_URL = ios.uploadToDiawi()
env.PKG_URL = env.DIAWI_URL
@@ -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);
@@ -1,10 +0,0 @@
#!/usr/bin/env sh
if rg --quiet --multiline '^\(ns.*\n^\s*\(:require\n(^\s*(;|#_).*\n)*(^\s*\[status-im2\.setup\.i18n-resources\W)' src/status_im2/core.cljs; then
exit 0
elif [ $? -eq 1 ]; then
echo "status-im2.setup.i18n-resources must be loaded first (be the first one in ns :require form) in status-im2.core"
echo "For more info, check the comment here https://github.com/status-im/status-mobile/pull/17618#discussion_r1361275489"
else
exit $?
fi
+4 -17
View File
@@ -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))
-2
View File
@@ -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)
-1
View File
@@ -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]
+20
View File
@@ -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))
+17 -9
View File
@@ -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])}))))
+1 -2
View File
@@ -523,8 +523,7 @@
(error-object->map response)]))}))
(defn save-multiaccount-and-login
[args]
(keycard/save-multiaccount-and-login card args))
[_])
(defn login
[args]
+2 -22
View File
@@ -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}]
+1 -8
View File
@@ -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]}]
+5 -8
View File
@@ -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]}
+1 -139
View File
@@ -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)))))
+4 -7
View File
@@ -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 -32
View File
@@ -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}]))
@@ -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)
+7 -8
View File
@@ -15,8 +15,6 @@
(def test-dir (.mkdtempSync fs test-dir-prefix))
(def initialized? (atom false))
(defn signal-received-callback
[a]
(re-frame/dispatch [:signals/signal-received a]))
@@ -24,12 +22,10 @@
;; We poll for signals, could not get callback working
(defn init!
[]
(when-not @initialized?
(.setSignalEventCallback native-status)
(reset! initialized? true)
(js/setInterval (fn []
(.pollSignal native-status signal-received-callback)
100))))
(.setSignalEventCallback native-status)
(js/setInterval (fn []
(.pollSignal native-status signal-received-callback)
100)))
(def status
(clj->js
@@ -121,6 +117,9 @@
:isAddress
(fn [address] (.isAddress native-status address))
:fleets
(fn [] (.fleets native-status))
:validateMnemonic
(fn [json callback] (callback (.validateMnemonic native-status json)))
+25 -19
View File
@@ -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?})}]})
+7 -15
View File
@@ -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,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))
+2
View File
@@ -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
+17
View File
@@ -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
@@ -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)]]]
@@ -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
+34 -3
View File
@@ -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))
+18 -43
View File
@@ -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
+31 -8
View File
@@ -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
@@ -1,4 +1,4 @@
(ns status-im2.integration-test.chat-test
(ns status-im2.integration-test.chat
(:require
[cljs.test :refer [deftest is]]
[day8.re-frame.test :as rf-test]
@@ -16,7 +16,7 @@
"0x0402905bed83f0bbf993cee8239012ccb1a8bc86907ead834c1e38476a0eda71414eed0e25f525f270592a2eebb01c9119a4ed6429ba114e51f5cb0a28dae1adfd")
(deftest one-to-one-chat-test
(h/log-headline :one-to-one-chat-test)
(h/log-headline one-to-one-chat-test)
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
@@ -1,4 +1,4 @@
(ns status-im2.integration-test.community-test
(ns status-im2.integration-test.community
(:require [cljs.test :refer [deftest]]
[day8.re-frame.test :as rf-test]
[re-frame.core :as rf]
@@ -1,4 +1,4 @@
(ns status-im2.integration-test.core-test
(ns status-im2.integration-test.core
(:require
[cljs.test :refer [deftest]]
[day8.re-frame.test :as rf-test]
@@ -8,14 +8,17 @@
status-im.subs.root
[status-im.utils.test :as utils.test]
status-im2.events
status-im2.integration-test.chat
status-im2.integration-test.wallet
status-im2.navigation.core
status-im2.subs.root
[test-helpers.integration :as h]))
(utils.test/init!)
(deftest initialize-app-test
(h/log-headline :initialize-app-test)
(rf-test/run-test-async
(utils.test/init!)
(rf/dispatch [:app-started])
(rf-test/wait-for
;; use initialize-view because it has the longest avg. time and
@@ -1,6 +1,6 @@
(ns status-im2.integration-test.wallet-test
(ns status-im2.integration-test.wallet
(:require
[cljs.test :refer [is]]
[cljs.test :refer [deftest is]]
[clojure.string :as string]
[day8.re-frame.test :as rf-test]
[re-frame.core :as rf]
@@ -12,9 +12,7 @@
status-im2.subs.root
[test-helpers.integration :as h]))
;; Workaround to skip test. Switch to `deftest` when test is fixed.
(defn create-wallet-account-test
[]
(deftest create-wallet-account-test
(h/log-headline :create-wallet-account-test)
(rf-test/run-test-async
(h/with-app-initialized
@@ -26,9 +24,7 @@
(h/logout)
(rf-test/wait-for [::logout/logout-method]))))))
;; Workaround to skip test. Switch to `deftest` when test is fixed.
(defn back-up-seed-phrase-test
[]
(deftest back-up-seed-phrase-test
(h/log-headline :back-up-seed-phrase-test)
(rf-test/run-test-async
(h/with-app-initialized
+9 -5
View File
@@ -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
+19 -6
View File
@@ -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]
+4
View File
@@ -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)
+35 -31
View File
@@ -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)))))
+92 -83
View File
@@ -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])))))
+12 -12
View File
@@ -4,21 +4,21 @@
(defmacro with-app-initialized
[& body]
`(do
(status-im.utils.test/init!)
(if (test-helpers.integration/app-initialized)
(do ~@body)
(do
(rf/dispatch [:app-started])
(rf-test/wait-for [:profile/get-profiles-overview-success]
~@body)))))
`(if (app-initialized)
(do ~@body)
(do
(rf/dispatch [:app-started])
(rf-test/wait-for
[:profile/get-profiles-overview-success]
~@body))))
(defmacro with-account
[& body]
`(if (test-helpers.integration/messenger-started)
`(if (messenger-started)
(do ~@body)
(do
(test-helpers.integration/create-multiaccount!)
(rf-test/wait-for [:status-im.transport.core/messenger-started]
(test-helpers.integration/assert-messenger-started)
(create-multiaccount!)
(rf-test/wait-for
[:status-im.transport.core/messenger-started]
(assert-messenger-started)
~@body))))
-1
View File
@@ -1,5 +1,4 @@
(ns test-helpers.integration
(:require-macros [test-helpers.integration])
(:require
[cljs.test :refer [is]]
[native-module.core :as native-module]
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "fix/shards-pubsub-topic",
"commit-sha1": "e7d9f59db4ccbf2c301d5b8dd705943be8c73097",
"src-sha256": "0hwy10ycjgbh332h1fl5hyw8j9nds0idqk980svaj76ckgsi7dlv"
"version": "test-shard-test",
"commit-sha1": "1a74a963384ec9598b6c6ed504cccdebd0a521f0",
"src-sha256": "0cbbqwjshq1m4z3mcrw7iyzv16xyp7ffpnbpfwx869mbhcnir0vm"
}
+60 -85
View File
@@ -1,7 +1,7 @@
import os
import re
import signal
import requests
import urllib.request
from contextlib import contextmanager
from dataclasses import dataclass
from datetime import datetime
@@ -161,57 +161,6 @@ def is_uploaded():
return True
@contextmanager
def _upload_time_limit(seconds):
def signal_handler(signum, frame):
raise TimeoutError("Apk upload took more than %s seconds" % seconds)
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(seconds)
try:
yield
finally:
signal.alarm(0)
class UploadApkException(Exception):
pass
def _upload_and_check_response(apk_file_path):
with _upload_time_limit(600):
with open(apk_file_path, 'rb') as f:
resp = sauce.storage._session.request('post', '/v1/storage/upload', files={'payload': f})
try:
if resp['item']['name'] != test_suite_data.apk_name:
raise UploadApkException("Incorrect apk was uploaded to Sauce storage, response:\n%s" % resp)
except KeyError:
raise UploadApkException("Error when uploading apk to Sauce storage, response:\n%s" % resp)
def _upload_and_check_response_with_retries(apk_file_path, retries=3):
for _ in range(retries):
try:
_upload_and_check_response(apk_file_path)
break
except (ConnectionError, RemoteDisconnected):
sleep(10)
def _download_apk(url):
# Absolute path adde to handle CI runs.
apk_path = os.path.join(os.path.dirname(__file__), test_suite_data.apk_name)
print('Downloading: %s' % url)
try:
resp = requests.get(url)
resp.raise_for_status()
except requests.RequestException as err:
print(resp.text)
raise err
with open(apk_path, 'wb') as f:
f.write(resp.content)
return apk_path
def pytest_configure(config):
global option
option = config.option
@@ -231,49 +180,75 @@ def pytest_configure(config):
apibase = 'eu-central-1.saucelabs.com'
else:
raise NotImplementedError("Unknown SauceLabs datacenter")
global sauce
sauce = SauceLab('https://api.' + apibase + '/', sauce_username, sauce_access_key)
if config.getoption('log_steps'):
import logging
logging.basicConfig(level=logging.INFO)
if config.getoption('env') == 'api':
return
if config.getoption('env') != 'api':
test_suite_data.apk_name = ([i for i in [i for i in config.getoption('apk').split('/')
if '.apk' in i]])[0]
if is_master(config):
pr_number = config.getoption('pr_number')
if config.getoption('testrail_report'):
if pr_number:
run_number = len(testrail_report.get_runs(pr_number)) + 1
run_name = 'PR-%s run #%s' % (pr_number, run_number)
else:
run_name = test_suite_data.apk_name
testrail_report.add_run(run_name)
if pr_number:
from github import Github
repo = Github(github_token).get_user('status-im').get_repo('status-mobile')
pull = repo.get_pull(int(pr_number))
pull.get_commits()[0].create_status(state='pending', context='Mobile e2e tests',
description='e2e tests are running')
if config.getoption('env') == 'sauce':
if not is_uploaded():
def _upload_and_check_response(apk_file_path):
@contextmanager
def _upload_time_limit(seconds):
def signal_handler(signum, frame):
raise TimeoutError("Apk upload took more than %s seconds" % seconds)
test_suite_data.apk_name = ([i for i in [i for i in config.getoption('apk').split('/')
if '.apk' in i]])[0]
if not is_master(config):
return
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(seconds)
try:
yield
finally:
signal.alarm(0)
pr_number = config.getoption('pr_number')
if config.getoption('testrail_report'):
if pr_number:
run_number = len(testrail_report.get_runs(pr_number)) + 1
run_name = 'PR-%s run #%s' % (pr_number, run_number)
else:
run_name = test_suite_data.apk_name
testrail_report.add_run(run_name)
with _upload_time_limit(600):
class UploadApkException(Exception):
pass
if pr_number:
from github import Github
repo = Github(github_token).get_user('status-im').get_repo('status-mobile')
pull = repo.get_pull(int(pr_number))
pull.get_commits()[0].create_status(
state='pending',
context='Mobile e2e tests',
description='e2e tests are running'
)
with open(apk_file_path, 'rb') as f:
resp = sauce.storage._session.request('post', '/v1/storage/upload',
files={'payload': f})
try:
if resp['item']['name'] != test_suite_data.apk_name:
raise UploadApkException(
"Incorrect apk was uploaded to Sauce storage, response:\n%s" % resp)
except KeyError:
raise UploadApkException(
"Error when uploading apk to Sauce storage, response:\n%s" % resp)
if config.getoption('env') == 'sauce' and not is_uploaded():
apk_src = config.getoption('apk')
if apk_src.startswith('http'):
apk_path = _download_apk(apk_src)
else:
apk_path = apk_src
if 'http' in config.getoption('apk'):
# it works with just a file_name, but I've added full path because not sure how it'll behave on the remote run (Jenkins)
file_path, to_remove = os.path.join(os.path.dirname(__file__), test_suite_data.apk_name), True
urllib.request.urlretrieve(config.getoption('apk'),
filename=file_path) # if url is not valid it raises an error
else:
file_path, to_remove = config.getoption('apk'), False
_upload_and_check_response_with_retries(apk_path)
if apk_src.startswith('http'):
os.remove(apk_path)
for _ in range(3):
try:
_upload_and_check_response(apk_file_path=file_path)
break
except (ConnectionError, RemoteDisconnected):
sleep(10)
if to_remove:
os.remove(file_path)
def pytest_unconfigure(config):
@@ -158,20 +158,20 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
except Failed:
self.errors.append("Link message reaction is not shown for the sender")
# self.home_2.just_fyi("Check 'Open in Status' option")
# # url_to_open = 'http://status.im' # ToDo: enable when a bug with Status link is fixed
# url_to_open = 'https://coinmarketcap.com/'
# self.chat_1.send_message(url_to_open)
# chat_element = self.chat_2.chat_element_by_text(url_to_open)
# if chat_element.is_element_displayed(120):
# chat_element.click_on_link_inside_message_body()
# web_view = self.chat_2.open_in_status_button.click()
# # if not web_view.element_by_text('Private, Secure Communication').is_element_displayed(60):
# if not web_view.element_by_text_part(
# "Today's Cryptocurrency Prices by Market Cap").is_element_displayed(30):
# self.errors.append('URL was not opened from 1-1 chat')
# else:
# self.errors.append("Message with URL was not received") # ToDo: temp
self.home_2.just_fyi("Check 'Open in Status' option")
# url_to_open = 'http://status.im' # ToDo: enable when a bug with Status link is fixed
url_to_open = 'https://coinmarketcap.com/'
self.chat_1.send_message(url_to_open)
chat_element = self.chat_2.chat_element_by_text(url_to_open)
if chat_element.is_element_displayed(120):
chat_element.click_on_link_inside_message_body()
web_view = self.chat_2.open_in_status_button.click()
# if not web_view.element_by_text('Private, Secure Communication').is_element_displayed(60):
if not web_view.element_by_text_part(
"Today's Cryptocurrency Prices by Market Cap").is_element_displayed(30):
self.errors.append('URL was not opened from 1-1 chat')
else:
self.errors.append("Message with URL was not received")
self.errors.verify_no_errors()
@@ -293,7 +293,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
sent_time_variants = self.chat_2.convert_device_time_to_chat_timestamp()
if timestamp not in sent_time_variants:
self.errors.append(
'Timestamp on message %s does not correspond expected %s' % (timestamp, sent_time_variants))
'Timestamp on message %s does not correspond expected [%s]' % (timestamp, *sent_time_variants))
except NoSuchElementException:
self.errors.append("No timestamp on message %s" % messages[0])
for message in [messages[1], messages[2]]:
@@ -248,7 +248,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.home.just_fyi("Check that can login with different user")
self.home.reopen_app(sign_in=False)
self.sign_in.show_profiles_button.wait_and_click()
self.sign_in.show_profiles_button.click()
self.sign_in.element_by_text(self.username).click()
self.sign_in.sign_in()
self.home.communities_tab.click()
@@ -257,7 +257,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.home.just_fyi("Check that can remove user from logged out state")
self.home.reopen_app(sign_in=False)
self.sign_in.show_profiles_button.wait_and_click()
self.sign_in.show_profiles_button.click()
user_card = self.sign_in.get_user(username=self.username)
user_card.open_user_options()
self.sign_in.remove_profile_button.click()
@@ -267,7 +267,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.home.just_fyi("Check that removed user is not shown in the list anymore")
self.home.reopen_app(sign_in=False)
self.sign_in.show_profiles_button.wait_and_click()
self.sign_in.show_profiles_button.click()
if self.sign_in.element_by_text(self.username).is_element_displayed():
self.errors.append("Removed user is re-appeared after relogin!")
+1
View File
@@ -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",