Compare commits

...
Author SHA1 Message Date
Prem Chaitanya Prathi ef1aafa644 feat: changes to publish to 2 peers for lightpush and not use store confirmations 2024-07-12 10:11:43 +05:30
Icaro Motta 54e4b597ed chore(communities): Hide non-implemented tabs in Discover communities (#20684)
Tabs "Open" and "Gated" in Discover communities screen were never implemented in
the code, they are dummies. We now hide them under the flag
config/show-not-implemented-features?, which is disabled for users.

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

To avoid regressions and be quicker, I opted to not remove the "All" tab even
though is the only one shown now, as that would require me to check non-trivial
code due to the fact that the tabs can be sticky as the user scrolls.
2024-07-11 22:38:18 -03:00
Icaro Motta 0b5dac0ad0 feat(settings): Revamp legacy Privacy and security settings (#20671)
Revamps the legacy "Privacy and security" screen to meet the new designs.

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

- Removed setting "Set dApp access permissions" (won't be used anymore).
- Removed setting "Display collectibles" (won't be used anymore).
- Removed setting "Chat link previews setting" (they already had no effect).
- Removed "Reset password setting". This setting is already supported in Profile
  > Password > Change password.
- Removed "Delete my profile". Profile deletion is already supported in the
  login screen.
- Moved setting "Show your profile picture" to Profile > Privacy and security.
- Moved setting "Accept new chats from <XYZ>" to "Allow new contact requests" in
  Profile > Messages. Now it's just a toggle.
- Moved Block screenshots (Android) or Hide Preview (iOS) which are both
  accessible in Profile > Privacy and security.
- Created function utils.navigation/navigate-back, but I only used this in 2
  namespaces to keep the PR under scope.

Areas that may be impacted: old legacy settings that are still relevant.
2024-07-11 22:23:17 -03:00
Mohamed Javid 180065129f fix(saved-addresses): clean QR scanned address (#20699)
This commit cleans the scanned QR address/result on the unmount of the add new saved address flow.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-11 20:01:55 +05:30
Mohamed Javid 866b854ee0 fix(key-pairs)_: error message on scanning different key pair QR (#20612)
This commit:

- update the connection string validation method to use the method from status-go
- updates the error message if the user tries to scan a different key pair QR for importing a missing key pair
- updates the text for exporting an individual key pair

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-11 15:55:00 +05:30
Shivek KhuranaandLungu Cristian 072370b0d6 🙅 Gracefully reject proposals and requests (#20649)
* 🙅 Gracefully reject proposals and requests

* 🔑 Remove redudant fx, send correct error

* ➡️ Docstring to comment

---------

Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
2024-07-11 13:03:14 +03:00
Shivek KhuranaandLungu Cristian d74edff9b9 2️⃣ Use v2 api for persisting sessions (#20648)
* 2️⃣ Use v2 api for persisting sessions

* 🗑️ Remove traces of REPL and v2 suffix

---------

Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
2024-07-11 12:50:42 +03:00
Andrea Maria Piana 0a0591f67a Add centralized metrics
https://github.com/status-im/status-go/compare/6e056348...1ef2434b

This commit adds support for pushing centralized metrics to mixpanel.

It uses an interceptor and only picks a few selected events to push
through.

In order to test:

1) Create an account in the app
2) Go to Settings->Privacy
3) Enable metrics

You should now see the events on the mixpanel dashboard (login with your
status-im account for access).
Only some example events are tracked, they are just for testing
2024-07-11 10:06:46 +01:00
Andrea Maria Piana 7a8db689f4 enable light client by default 2024-07-11 09:01:23 +01:00
John NgeiandYevheniia Berdnyk 311fde9409 chore: remove identifiers screens (#20503)
* chore: remove identifiers screens so users are navigated straight to enable notifications during onboarding

* removed navigated back button from enable notification screen

* fix top margin

* e2e: updated sign in flow

* make lint-fix

---------

Co-authored-by: Yevheniia Berdnyk <ie.berdnyk@gmail.com>
2024-07-11 02:09:03 +02:00
Yevheniia Berdnyk f89b66f562 e2e: adding android.gpu.mode capability to fix emulators crash 2024-07-11 02:43:32 +03:00
Yevheniia Berdnyk d179cbf59b e2e: updated discover communities test 2024-07-10 19:53:48 +05:30
Parvesh Monu 7ff7e78691 fix user lands on the Home screen after closing a community opened from Discover Communities 2024-07-10 19:53:47 +05:30
Omar Basem 6c352397ab fix(wallet): asset sorting (#20659)
* fix(wallet): asset sorting (#20659)
2024-07-10 14:49:24 +04:00
Mohsen 3521421098 [#20543] fix: incorrect black background behind floating button (#20585) 2024-07-09 21:12:18 +03:30
Omar Basem f70a743a8c Fix(wallet): address validation (#20674)
* fix(wallet): address validation (#20674)
2024-07-09 15:59:48 +04:00
NikolayandJamie Caprani a2178951d7 chore(wallet): import private key - backend integration
Co-authored-by: Jamie Caprani <jamiecaprani@gmail.com>
2024-07-09 03:49:31 -07:00
86 changed files with 1126 additions and 1067 deletions
-1
View File
@@ -26,7 +26,6 @@ APN_TOPIC=im.status.ethereum.pr
COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
COMMANDS_ENABLED=1
TWO_MINUTES_SYNCING=1
SWAP_ENABLED=1
-1
View File
@@ -18,6 +18,5 @@ PARTITIONED_TOPIC=0
ENABLE_ROOT_ALERT=1
MAX_IMAGES_BATCH=1
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
+6
View File
@@ -457,6 +457,12 @@ android-tail-geth: export VERSION ?= debug
android-tail-geth:
adb shell 'while true; do cat; sleep 1; done < /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
android-clean-geth: export TARGET := android-sdk
android-clean-geth: export VERSION ?= debug
android-clean-geth:
adb shell 'rm /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
android-logcat: export TARGET := android-sdk
android-logcat: ##@other Read status-mobile logs from Android phone using adb
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
@@ -246,6 +246,14 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
utils.executeRunnableStatusGoMethod({ Statusgo.openAccounts(rootDir) }, callback)
}
@ReactMethod
private fun initializeApplication(request: String, callback: Callback) {
Log.d(TAG, "initializeApplication")
Log.d(TAG, "[Initializing application $request")
utils.executeRunnableStatusGoMethod({ Statusgo.initializeApplication(request) }, callback)
}
@ReactMethod
fun logout() {
Log.d(TAG, "logout")
@@ -76,6 +76,16 @@ class StatusModule(private val reactContext: ReactApplicationContext, private va
utils.executeRunnableStatusGoMethod({ Statusgo.getNodeConfig() }, callback)
}
@ReactMethod
fun addCentralizedMetric(request: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.addCentralizedMetric(request) }, callback)
}
@ReactMethod
fun toggleCentralizedMetrics(request: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.toggleCentralizedMetrics(request) }, callback)
}
@ReactMethod
fun deleteImportedKey(keyUID: String, address: String, password: String, callback: Callback) {
val keyStoreDir = utils.getKeyStorePath(keyUID)
@@ -153,4 +153,9 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
return strArray
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun validateConnectionString(connectionString: String): String {
return Statusgo.validateConnectionString(connectionString)
}
}
@@ -195,6 +195,15 @@ RCT_EXPORT_METHOD(verifyDatabasePassword:(NSString *)keyUID
callback(@[result]);
}
RCT_EXPORT_METHOD(initializeApplication:(NSString *)request
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"initializeApplication() method called");
#endif
NSString *result = StatusgoInitializeApplication(request);
callback(@[result]);
}
RCT_EXPORT_METHOD(openAccounts:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"OpenAccounts() method called");
@@ -176,6 +176,24 @@ RCT_EXPORT_METHOD(appStateChange:(NSString *)type) {
StatusgoAppStateChange(type);
}
RCT_EXPORT_METHOD(addCentralizedMetric:(NSString *)request
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"addCentralizedMetric() method called");
#endif
NSString *result = StatusgoAddCentralizedMetric(request);
callback(@[result]);
}
RCT_EXPORT_METHOD(toggleCentralizedMetrics:(NSString *)request
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"toggleCentralizedMetrics() method called");
#endif
NSString *result = StatusgoToggleCentralizedMetrics(request);
callback(@[result]);
}
RCT_EXPORT_METHOD(startLocalNotifications) {
#if DEBUG
NSLog(@"StartLocalNotifications() method called");
@@ -128,4 +128,8 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(toChecksumAddress:(NSString *)address) {
return StatusgoToChecksumAddress(address);
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(validateConnectionString:(NSString *)cs) {
return StatusgoValidateConnectionString(cs);
}
@end
+32 -1
View File
@@ -302,6 +302,36 @@ void _MultiAccountStoreAccount(const FunctionCallbackInfo<Value>& args) {
delete c;
}
void _InitializeApplication(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 1) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for InitializeApplication")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for request")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
// Call exported Go function, which returns a C string
char *c = InitializeApplication(arg0);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _InitKeystore(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
@@ -1935,6 +1965,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, "initializeApplication", _InitializeApplication);
NODE_SET_METHOD(exports, "fleets", _Fleets);
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
@@ -1972,7 +2003,7 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "signTypedData", _SignTypedData);
NODE_SET_METHOD(exports, "sendTransaction", _SendTransaction);
NODE_SET_METHOD(exports, "appStateChange", _AppStateChange);
NODE_SET_METHOD(exports, "setSignalEventCallback", _SetSignalEventCallback);
NODE_SET_METHOD(exports, "setSignalEventCallback", _SetSignalEventCallback);
NODE_SET_METHOD(exports, "validateNodeConfig", _ValidateNodeConfig);
NODE_SET_METHOD(exports, "hashTypedData", _HashTypedData);
NODE_SET_METHOD(exports, "recover", _Recover);
+2
View File
@@ -45,6 +45,8 @@ SECRETS_ENV_VARS=(
'INFURA_TOKEN'
'INFURA_TOKEN_SECRET'
'OPENSEA_API_KEY'
'MIXPANEL_APP_ID'
'MIXPANEL_TOKEN'
'POKT_TOKEN'
)
+6
View File
@@ -67,6 +67,8 @@
:closure-defines
{status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
@@ -102,6 +104,8 @@
{status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
@@ -143,6 +147,8 @@
status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
-1
View File
@@ -26,7 +26,6 @@
legacy.status-im.ui.components.invite.events
[legacy.status-im.ui.components.react :as react]
legacy.status-im.ui.screens.notifications-settings.events
legacy.status-im.ui.screens.privacy-and-security-settings.events
[legacy.status-im.utils.dimensions :as dimensions]
legacy.status-im.utils.logging.core
[legacy.status-im.utils.utils :as utils]
@@ -120,12 +120,3 @@
{:events [:multiaccounts.ui/switch-backup-enabled]}
[cofx enabled?]
(multiaccount-update cofx :backup-enabled? enabled? {}))
(rf/defn toggle-opensea-nfts-visibility
{:events [::toggle-opensea-nfts-visiblity]}
[cofx visible?]
(rf/merge cofx
{:db (assoc-in (:db cofx) [:profile/profile :opensea-enabled?] visible?)
;; need to add fully qualified namespace to counter circular deps
:dispatch [:legacy.status-im.wallet.core/fetch-collectibles-collection]}
(multiaccount-update :opensea-enabled? visible? {})))
@@ -1,11 +0,0 @@
(ns legacy.status-im.ui.screens.dapps-permissions.styles
(:require
[legacy.status-im.ui.components.colors :as colors]))
(def icon-container
{:width 40
:height 40
:border-radius 20
:background-color colors/gray-lighter
:align-items :center
:justify-content :center})
@@ -1,64 +0,0 @@
(ns legacy.status-im.ui.screens.dapps-permissions.views
(:require-macros [legacy.status-im.utils.views :as views])
(:require
[legacy.status-im.ui.components.colors :as colors]
[legacy.status-im.ui.components.core :as quo]
[legacy.status-im.ui.components.icons.icons :as icons]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.list.views :as list]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.components.topbar :as topbar]
[legacy.status-im.ui.screens.dapps-permissions.styles :as styles]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[utils.i18n :as i18n]))
(defn d-icon
[]
[react/view styles/icon-container
[icons/icon :main-icons/dapp {:color colors/gray}]])
(defn prepare-items
[{:keys [dapp permissions]}]
{:title dapp
:chevron true
:on-press #(re-frame/dispatch [:navigate-to :manage-dapps-permissions
{:dapp dapp :permissions permissions}])
:icon [d-icon]})
(defn prepare-items-manage
[name]
(fn [permission]
{:title (cond
(= permission constants/dapp-permission-web3)
name
(= permission constants/dapp-permission-contact-code)
(i18n/label :t/contact-code))
:size :small
:accessory [icons/icon :main-icons/check {}]}))
(views/defview dapps-permissions
[]
(views/letsubs [permissions [:dapps/permissions]]
[list/flat-list
{:data (vec (map prepare-items (vals permissions)))
:key-fn (fn [_ i] (str i))
:render-fn list.item/list-item}]))
(views/defview manage
[]
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]
{:keys [name]} [:dapps-account]]
[:<>
[topbar/topbar {:title dapp}]
[list/flat-list
{:data (vec (map (prepare-items-manage name) permissions))
:key-fn (fn [_ i] (str i))
:render-fn list.item/list-item}]
[react/view
{:padding-vertical 16
:padding-horizontal 16}
[quo/button
{:theme :negative
:on-press #(re-frame/dispatch [:dapps/revoke-access dapp])}
(i18n/label :t/revoke-access)]]]))
@@ -1,13 +0,0 @@
(ns legacy.status-im.ui.screens.link-previews-settings.styles)
(def link-preview-settings-image
{:height 100
:align-self :center
:margin-top 16})
(def whitelist-container
{:flex-direction :row
:justify-content :space-between})
(def enable-all
{:align-self :flex-end})
@@ -1,67 +0,0 @@
(ns legacy.status-im.ui.screens.link-previews-settings.views
(:require-macros [legacy.status-im.utils.views :as views])
(:require
[legacy.status-im.react-native.resources :as resources]
[legacy.status-im.ui.components.core :as components]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.list.views :as list]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.screens.link-previews-settings.styles :as styles]
[quo.core :as quo]
[re-frame.core :as re-frame]
[status-im.contexts.chat.messenger.messages.link-preview.events]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn prepare-urls-items-data
[link-previews-enabled-sites]
(fn [{:keys [title address]}]
(let [enabled? (contains? link-previews-enabled-sites title)]
{:title title
:subtitle address
:size :small
:accessory :switch
:active (contains? link-previews-enabled-sites title)
:on-press #(re-frame/dispatch
[:chat.ui/enable-link-previews title ((complement boolean) enabled?)])})))
(views/defview link-previews-settings
[]
(views/letsubs [link-previews-whitelist [:link-previews-whitelist]
link-previews-enabled-sites [:link-preview/enabled-sites]]
(let [all-enabled (= (count link-previews-whitelist) (count link-previews-enabled-sites))]
[:<>
[quo/page-nav
{:type :title
:title (i18n/label :t/chat-link-previews)
:background :blur
:icon-name :i/close
:on-press #(rf/dispatch [:navigate-back])}]
[react/image
{:source (resources/get-theme-image :unfurl)
:style styles/link-preview-settings-image}]
[components/text {:style {:margin 16}}
(i18n/label :t/you-can-choose-preview-websites)]
[components/separator {:style {:margin-vertical 8}}]
[react/view styles/whitelist-container
[components/list-header (i18n/label :t/websites)]
(when (> (count link-previews-whitelist) 1)
[components/button
{:on-press #(re-frame/dispatch [:chat.ui/enable-all-link-previews
link-previews-whitelist
(not all-enabled)])
:type :secondary
:style styles/enable-all}
(if all-enabled
(i18n/label :t/disable-all)
(i18n/label :t/enable-all))])]
[list/flat-list
{:data (vec (map (prepare-urls-items-data link-previews-enabled-sites)
link-previews-whitelist))
:key-fn (fn [_ i] (str i))
:render-fn list.item/list-item
:footer [quo/text
{:color :secondary
:style {:margin 16}} (i18n/label :t/previewing-may-share-metadata)]}]])))
@@ -1,81 +0,0 @@
(ns legacy.status-im.ui.screens.privacy-and-security-settings.delete-profile
(:require
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[legacy.status-im.ui.components.core :as quo]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.screens.privacy-and-security-settings.events :as delete-profile]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.contexts.profile.utils :as profile.utils]
[utils.i18n :as i18n]
[utils.security.core :as security]))
(defn valid-password?
[password]
(>= (count password) 6))
(defn on-delete-profile
[password]
#(do
(re-frame/dispatch
[::delete-profile/delete-profile @password])
(reset! password nil)))
(defn delete-profile
[]
(let [password (reagent/atom nil)
text-input-ref (atom nil)]
(fn []
(let [profile @(re-frame/subscribe [:profile/profile])
error @(re-frame/subscribe [:delete-profile/error])
keep-keys-on-keycard? @(re-frame/subscribe
[:delete-profile/keep-keys-on-keycard?])]
(when (and @text-input-ref error (not @password))
(.clear ^js @text-input-ref))
[react/keyboard-avoiding-view {:style {:flex 1}}
[react/scroll-view {:style {:flex 1}}
[react/view {:style {:align-items :center}}
[quo/text
{:weight :bold
:size :x-large}
(i18n/label :t/delete-profile)]]
[list.item/list-item
{:title (profile.utils/displayed-name profile)
:icon [chat-icon.screen/contact-icon-contacts-tab profile]}]
[quo/text
{:style {:margin-horizontal 24}
:align :center
:color :negative}
(i18n/label :t/delete-profile-warning)]
[quo/text-input
{:style {:margin-horizontal 36
:margin-top 36}
:show-cancel false
:secure-text-entry true
:return-key-type :next
:on-submit-editing nil
:auto-focus true
:on-change-text #(reset! password (security/mask-data %))
:bottom-value 36
:get-ref #(reset! text-input-ref %)
:error (when (and error (not @password))
(if (= :wrong-password error)
(i18n/label :t/wrong-password)
(str error)))}]]
[react/view {:style {:align-items :center}}
[quo/separator]
(when (not keep-keys-on-keycard?)
[quo/text
{:style {:margin-horizontal 24 :margin-bottom 16}
:align :center
:color :negative}
(i18n/label :t/delete-profile-warning)])
[react/view
{:style {:margin-vertical 8}}
[quo/button
{:on-press (on-delete-profile password)
:theme :negative
:accessibility-label :delete-profile-confirm
:disabled ((complement valid-password?) @password)}
(i18n/label :t/delete-profile)]]]]))))
@@ -1,73 +0,0 @@
(ns legacy.status-im.ui.screens.privacy-and-security-settings.events
(:require
[clojure.string :as string]
[legacy.status-im.utils.deprecated-types :as types]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
(defn safe-blank?
[s]
(or (not s)
(string/blank? s)))
(re-frame/reg-fx
::delete-profile
(fn [{:keys [address key-uid callback masked-password]}]
(let [hashed-password
(-> masked-password
security/safe-unmask-data
native-module/sha3)]
(native-module/verify
address
hashed-password
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(log/info "[delete-profile] verify-password" result error)
(if-not (safe-blank? error)
(callback :wrong-password nil)
(native-module/delete-multiaccount
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(callback error nil)))))))))))
(rf/defn delete-profile
{:events [::delete-profile]}
[{:keys [db] :as cofx} masked-password]
(log/info "[delete-profile] delete")
(let [{:keys [key-uid wallet-root-address]} (:profile/profile db)]
{:db (dissoc db :delete-profile/error)
::delete-profile
{:masked-password masked-password
:key-uid key-uid
:address wallet-root-address
:callback
(fn [error result]
(log/info "[delete-profile] callback" error)
(if (safe-blank? error)
(re-frame/dispatch [::on-delete-profile-success result])
(re-frame/dispatch [::on-delete-profile-failure error])))}}))
(rf/defn on-delete-profile-success
{:events [::on-delete-profile-success]}
[cofx]
(log/info "[delete-profile] on-success")
{:effects.utils/show-popup
{:title (i18n/label :t/profile-deleted-title)
:content (i18n/label :t/profile-deleted-content)
:on-dismiss #(re-frame/dispatch [:logout])}})
(rf/defn on-delete-profile-failure
{:events [::on-delete-profile-failure]}
[{:keys [db]} error]
(log/info "[delete-profile] on-failure" error)
{:db (assoc db :delete-profile/error error)})
(rf/defn keep-keys-on-keycard
{:events [::keep-keys-on-keycard]}
[{:keys [db] :as cofx} checked?]
{:db (assoc-in db [:delete-profile/keep-keys-on-keycard?] checked?)})
@@ -1,34 +0,0 @@
(ns legacy.status-im.ui.screens.privacy-and-security-settings.messages-from-contacts-only
(:require-macros [legacy.status-im.utils.views :as views])
(:require
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(rf/defn handle-messages-from-contacts-only-switched
{:events [::messages-from-contacts-only-switched]}
[cofx value]
(multiaccounts.update/multiaccount-update cofx
:messages-from-contacts-only
value
{}))
(views/defview messages-from-contacts-only-view
[]
(views/letsubs [{:keys [messages-from-contacts-only]} [:profile/profile]]
[react/view {:margin-top 8}
[list.item/list-item
{:active (not messages-from-contacts-only)
:accessory :radio
:title (i18n/label :t/anyone)
:on-press #(re-frame/dispatch [::messages-from-contacts-only-switched false])}]
[list.item/list-item
{:active messages-from-contacts-only
:accessory :radio
:title (i18n/label :t/contacts)
:subtitle (i18n/label :t/messages-from-contacts-only-subtitle)
:subtitle-max-lines 4
:on-press #(re-frame/dispatch [::messages-from-contacts-only-switched true])}]]))
@@ -1,175 +0,0 @@
(ns legacy.status-im.ui.screens.privacy-and-security-settings.views
(:require
[legacy.status-im.multiaccounts.reset-password.core :as reset-password]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[legacy.status-im.ui.components.core :as components]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.react :as react]
[quo.core :as quo]
[re-frame.core :as re-frame]
[react-native.platform :as platform]
[status-im.config :as config]
[status-im.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf])
(:require-macros [legacy.status-im.utils.views :as views]))
(defn separator
[]
[components/separator {:style {:margin-vertical 8}}])
(def titles
{constants/profile-pictures-visibility-contacts-only (i18n/label :t/recent-recipients)
constants/profile-pictures-visibility-everyone (i18n/label :t/everyone)
constants/profile-pictures-visibility-none (i18n/label :t/none)
constants/profile-pictures-show-to-contacts-only (i18n/label :t/recent-recipients)
constants/profile-pictures-show-to-everyone (i18n/label :t/everyone)
constants/profile-pictures-show-to-none (i18n/label :t/none)})
(views/defview privacy-and-security
[]
(views/letsubs [{:keys [preview-privacy?
messages-from-contacts-only
webview-allow-permission-requests?
opensea-enabled?
profile-pictures-visibility]}
[:profile/profile]
has-picture [:profile/has-picture]
profile-pictures-show-to [:multiaccount/profile-pictures-show-to]]
[:<>
[quo/page-nav
{:type :no-title
:background :blur
:icon-name :i/close
:on-press #(rf/dispatch [:navigate-back])}]
[react/scroll-view {:padding-vertical 8}
[components/list-header (i18n/label :t/privacy)]
[list.item/list-item
{:size :small
:title (i18n/label :t/set-dapp-access-permissions)
:on-press #(re-frame/dispatch [:navigate-to :dapps-permissions])
:accessibility-label :dapps-permissions-button
:chevron true}]
[list.item/list-item
{:size :small
:title (if platform/android?
(i18n/label :t/hide-content-when-switching-apps)
(i18n/label :t/hide-content-when-switching-apps-ios))
:container-margin-bottom 8
:active preview-privacy?
:accessory :switch
:on-press #(re-frame/dispatch
[:profile.settings/change-preview-privacy
((complement boolean) preview-privacy?)])}]
(when config/collectibles-enabled?
[list.item/list-item
{:size :small
:title (i18n/label :t/display-collectibles)
:container-margin-bottom 8
:active opensea-enabled?
:accessory :switch
:on-press #(re-frame/dispatch
[::multiaccounts.update/toggle-opensea-nfts-visiblity
(not opensea-enabled?)])}])
[list.item/list-item
{:size :small
:title (i18n/label :t/chat-link-previews)
:chevron true
:on-press #(re-frame/dispatch [:open-modal :legacy-link-previews-settings])
:accessibility-label :chat-link-previews}]
[list.item/list-item
{:size :small
:title (i18n/label :t/accept-new-chats-from)
:chevron true
:accessory :text
:accessory-text (i18n/label (if messages-from-contacts-only
:t/contacts
:t/anyone))
:on-press #(re-frame/dispatch [:navigate-to :messages-from-contacts-only])
:accessibility-label :accept-new-chats-from}]
[list.item/list-item
{:size :small
:title (i18n/label :t/reset-password)
:chevron true
:accessory :text
:on-press #(do
(re-frame/dispatch [::reset-password/clear-form-vals])
(re-frame/dispatch [:navigate-to :reset-password]))
:accessibility-label :reset-password}]
(when platform/android?
[list.item/list-item
{:size :small
:title (i18n/label :t/webview-camera-permission-requests)
:active webview-allow-permission-requests?
:accessory :switch
:subtitle (i18n/label :t/webview-camera-permission-requests-subtitle)
:subtitle-max-lines 2
:on-press #(re-frame/dispatch
[:profile.settings/profile-update
:webview-allow-permission-requests?
((complement boolean) webview-allow-permission-requests?)])}])
[separator]
[components/list-header (i18n/label :t/privacy-photos)]
[list.item/list-item
{:size :small
:title (i18n/label :t/show-profile-pictures)
:accessibility-label :show-profile-pictures
:accessory :text
:accessory-text (get titles profile-pictures-visibility)
:on-press #(re-frame/dispatch [:navigate-to :privacy-and-security-profile-pic])
:chevron true}]
[list.item/list-item
{:size :small
:title (i18n/label :t/show-profile-pictures-to)
:disabled (not has-picture)
:accessibility-label :show-profile-pictures-to
:accessory :text
:accessory-text (get titles profile-pictures-show-to)
:on-press #(re-frame/dispatch [:navigate-to
:privacy-and-security-profile-pic-show-to])
:chevron true}]
[separator]
[list.item/list-item
{:size :small
:theme :negative
:title (i18n/label :t/delete-my-profile)
:on-press #(re-frame/dispatch [:navigate-to :delete-profile])
:accessibility-label :dapps-permissions-button
:chevron true}]]]))
(defn ppst-radio-item
[id value]
[list.item/list-item
{:active (= value id)
:accessory :radio
:title (get titles id)
:on-press #(re-frame/dispatch [:profile.settings/change-profile-pictures-show-to id])}])
(views/defview profile-pic-show-to
[]
(views/letsubs [{:keys [profile-pictures-show-to]} [:profile/profile]]
[react/view {:margin-top 8}
[ppst-radio-item constants/profile-pictures-show-to-everyone profile-pictures-show-to]
[ppst-radio-item constants/profile-pictures-show-to-contacts-only profile-pictures-show-to]
[ppst-radio-item constants/profile-pictures-show-to-none profile-pictures-show-to]
[react/view {:style {:margin-horizontal 16}}
[components/text {:color :secondary}
(i18n/label :t/privacy-show-to-warning)]]]))
(defn ppvf-radio-item
[id value]
[list.item/list-item
{:active (= value id)
:accessory :radio
:title (get titles id)
:on-press #(re-frame/dispatch [:profile.settings/profile-update :profile-pictures-visibility id])}])
(views/defview profile-pic
[]
(views/letsubs [{:keys [profile-pictures-visibility]} [:profile/profile]]
[react/view {:margin-top 8}
[ppvf-radio-item constants/profile-pictures-visibility-everyone profile-pictures-visibility]
[ppvf-radio-item constants/profile-pictures-visibility-contacts-only profile-pictures-visibility]
[ppvf-radio-item constants/profile-pictures-visibility-none profile-pictures-visibility]]))
@@ -13,12 +13,6 @@
[]
[rn/scroll-view {:flex 1}
[components/list-header "Legacy settings"]
[list.item/list-item
{:icon :main-icons/security
:title (i18n/label :t/privacy-and-security)
:accessibility-label :privacy-and-security-settings-button
:chevron true
:on-press #(re-frame/dispatch [:open-modal :legacy-privacy-and-security])}]
[list.item/list-item
{:icon :main-icons/mobile
:title (i18n/label :t/sync-settings)
@@ -8,12 +8,10 @@
[legacy.status-im.ui.screens.bug-report :as bug-report]
[legacy.status-im.ui.screens.communities.invite :as communities.invite]
[legacy.status-im.ui.screens.communities.members :as members]
[legacy.status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
[legacy.status-im.ui.screens.default-sync-period-settings.view :as default-sync-period-settings]
[legacy.status-im.ui.screens.fleet-settings.views :as fleet-settings]
[legacy.status-im.ui.screens.glossary.view :as glossary]
[legacy.status-im.ui.screens.help-center.views :as help-center]
[legacy.status-im.ui.screens.link-previews-settings.views :as link-previews-settings]
[legacy.status-im.ui.screens.log-level-settings.views :as log-level-settings]
[legacy.status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings]
[legacy.status-im.ui.screens.notifications-settings.views :as notifications-settings]
@@ -21,10 +19,6 @@
[legacy.status-im.ui.screens.offline-messaging-settings.views :as offline-messaging-settings]
[legacy.status-im.ui.screens.pairing.views :as pairing]
[legacy.status-im.ui.screens.peers-stats :as peers-stats]
[legacy.status-im.ui.screens.privacy-and-security-settings.delete-profile :as delete-profile]
[legacy.status-im.ui.screens.privacy-and-security-settings.messages-from-contacts-only :as
messages-from-contacts-only]
[legacy.status-im.ui.screens.privacy-and-security-settings.views :as privacy-and-security]
[legacy.status-im.ui.screens.profile.seed.views :as profile.seed]
[legacy.status-im.ui.screens.profile.user.views :as profile.user]
[legacy.status-im.ui.screens.progress.views :as progress]
@@ -94,17 +88,6 @@
:insets {:top? platform/android?}}
:component profile.user/legacy-settings}
;; PRIVACY AND SECURITY
{:name :legacy-privacy-and-security
:options {:topBar {:visible false}
:insets {:top? platform/android?}}
:component privacy-and-security/privacy-and-security}
{:name :legacy-link-previews-settings
:options {:topBar {:visible false}
:insets {:top? platform/android?}}
:component link-previews-settings/link-previews-settings}
;; SYNC
{:name :legacy-sync-settings
:options {:topBar {:visible false}
@@ -150,25 +133,6 @@
{:name :edit-mailserver
:options {:insets {:top? true}}
:component edit-mailserver/edit-mailserver}
{:name :dapps-permissions
:options {:topBar (topbar-options :t/dapps-permissions)
:insets {:top? true}}
:component dapps-permissions/dapps-permissions}
{:name :messages-from-contacts-only
:options {:topBar (topbar-options :t/accept-new-chats-from)
:insets {:top? true}}
:component messages-from-contacts-only/messages-from-contacts-only-view}
{:name :privacy-and-security-profile-pic-show-to
:options {:topbar (topbar-options :t/show-profile-pictures-to)
:insets {:top? true}}
:component privacy-and-security/profile-pic-show-to}
{:name :privacy-and-security-profile-pic
:options {:topBar (topbar-options :t/show-profile-pictures)
:insets {:top? true}}
:component privacy-and-security/profile-pic}
{:name :manage-dapps-permissions
:options {:insets {:top? true}}
:component dapps-permissions/manage}
{:name :rpc-usage-info
:options {:topBar (topbar-options :t/rpc-usage-info)
:insets {:top? true}}
@@ -196,9 +160,6 @@
:options {:topBar (topbar-options :t/reset-password)
:insets {:top? true}}
:component reset-password/reset-password}
{:name :delete-profile
:insets {:bottom? true}
:component delete-profile/delete-profile}
{:name :default-sync-period-settings
:options {:topBar (topbar-options :t/default-sync-period)
:insets {:top? true}}
-130
View File
@@ -1,130 +0,0 @@
(ns legacy.status-im.utils.test
(:require
[legacy.status-im.utils.deprecated-types :as types]
[re-frame.core :as re-frame]))
(def native-status (js/require "../../modules/react-native-status/nodejs/bindings"))
(def fs (js/require "fs"))
(def path (js/require "path"))
(def os (js/require "os"))
(def tmpdir (.tmpdir os))
(def test-dir-prefix (.join path tmpdir "status-mobile-tests"))
(def test-dir (.mkdtempSync fs test-dir-prefix))
(def initialized? (atom false))
(defn signal-received-callback
[a]
(re-frame/dispatch [:signals/signal-received a]))
;; 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))))
(def ui-helper
(clj->js
{:clearCookies identity
:clearStorageAPIs identity}))
(def encryption-utils
(clj->js
{:sha3
(fn [s] (.sha3 native-status s))
:setBlankPreviewFlag
identity
:encodeTransfer
(fn [to-norm amount-hex]
(.encodeTransfer native-status to-norm amount-hex))
:hexToNumber
(fn [hex] (.hexToNumber native-status hex))
:decodeParameters
(fn [decode-param-json]
(.decodeParameters native-status decode-param-json))
:numberToHex
(fn [num-str] (.numberToHex native-status num-str))
:initKeystore
(fn [key-uid callback]
(callback (.initKeystore native-status
(str test-dir "/keystore/" key-uid))))
:multiformatDeserializePublicKey
(fn [public-key deserialization-key callback]
(callback (.multiformatDeserializePublicKey
native-status
public-key
deserialization-key)))}))
(def account-manager
(clj->js
{:openAccounts
(fn [callback]
(callback (.openAccounts native-status test-dir)))
:createAccountAndLogin
(fn [request] (.createAccountAndLogin native-status request))
:logout
(fn [] (.logout native-status))
:multiAccountImportMnemonic
(fn [json callback]
(callback (.multiAccountImportMnemonic native-status json)))
:multiAccountLoadAccount
(fn [json callback]
(callback (.multiAccountLoadAccount native-status json)))
:multiAccountDeriveAddresses
(fn [json callback]
(callback (.multiAccountDeriveAddresses native-status json)))
:multiAccountGenerateAndDeriveAddresses
(fn [json callback]
(callback (.multiAccountGenerateAndDeriveAddresses native-status json)))
:multiAccountStoreDerived
(fn [json callback]
(callback (.multiAccountStoreDerivedAccounts native-status json)))}))
(def utils
(clj->js
{:backupDisabledDataDir
(fn [] (str test-dir "/backup"))
:keystoreDir (fn [] "")
:toChecksumAddress
(fn [address] (.toChecksumAddress native-status address))
:checkAddressChecksum
(fn [address] (.checkAddressChecksum native-status address))
:validateMnemonic
(fn [json callback] (callback (.validateMnemonic native-status json)))
:isAddress
(fn [address] (.isAddress native-status address))}))
(def log-manager
(clj->js
{:logFileDirectory
(fn [] (str test-dir "/log"))
:initLogging
(fn [enabled mobile-system log-level callback]
(callback (.initLogging native-status
(types/clj->json {:Enabled enabled
:MobileSystem mobile-system
:Level log-level
:File (str test-dir "/geth.log")}))))}))
(def network
(clj->js
{:callPrivateRPC
(fn [payload callback]
(callback (.callPrivateRPC native-status payload)))}))
(def status
(clj->js
{:getNodeConfig
(fn [] (types/clj->json {:WakuV2Config ""}))
:fleets
(fn [] (.fleets native-status))
:startLocalNotifications
identity}))
+21 -5
View File
@@ -72,10 +72,12 @@
(log/debug "[native-module] init-keystore" key-uid)
(.initKeystore ^js (encryption) key-uid callback))
(defn open-accounts
[callback]
(log/debug "[native-module] open-accounts")
(.openAccounts ^js (account-manager) #(callback (types/json->clj %))))
(defn initialize-application
[request callback]
(log/debug "[native-module] initialize-application")
(.initializeApplication ^js (account-manager)
(types/clj->json request)
#(callback (types/json->clj %))))
(defn prepare-dir-and-update-config
[key-uid config callback]
@@ -513,6 +515,14 @@
(let [result (.checkAddressChecksum ^js (utils) address)]
(types/json->clj result)))
(defn toggle-centralized-metrics
[enabled callback]
(.toggleCentralizedMetrics ^js (status) (types/clj->json {:enabled enabled}) callback))
(defn add-centralized-metric
[metric]
(.addCentralizedMetric ^js (status) (types/clj->json metric) #(log/debug "pushed metric" % metric)))
(defn address?
[address]
(log/debug "[native-module] address?")
@@ -533,6 +543,13 @@
(log/debug "[native-module] validate-mnemonic")
(.validateMnemonic ^js (utils) mnemonic callback)))
(defn validate-connection-string
[connection-string]
(log/debug "[native-module] validate-connection-string")
(->> connection-string
(.validateConnectionString ^js (utils))
types/json->clj))
(defn delete-multiaccount
"Delete multiaccount from database, deletes multiaccount's database and
key files."
@@ -643,7 +660,6 @@
(native-utils/promisify-native-module-call create-account-from-private-key private-key))
([private-key callback]
(log/debug "[native-module] create-account-from-private-key")
(.createAccountFromPrivateKey ^js (account-manager)
(types/clj->json {:privateKey private-key})
callback)))
@@ -51,7 +51,7 @@
(defn color
[blur? theme]
{:color (if blur?
colors/white-opa-70
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
(defn label-dot
+2
View File
@@ -22,6 +22,8 @@
(clj->js {:proposal proposal
:supportedNamespaces supported-namespaces})))
;; Get an error from this list:
;; https://github.com/WalletConnect/walletconnect-monorepo/blob/c6e9529418a0c81d4efcc6ac4e61f242a50b56c5/packages/utils/src/errors.ts
(defn get-sdk-error
[error-key]
(getSdkError error-key))
@@ -1,6 +1,7 @@
(ns status-im.common.floating-button-page.floating-container.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[status-im.common.floating-button-page.floating-container.style :as style]))
@@ -9,9 +10,10 @@
[child]
(let [theme (quo.theme/use-theme)]
[quo/blur
{:blur-amount 12
:blur-radius 12
:blur-type theme}
{:blur-amount 52
:blur-radius 20
:blur-type :transparent
:blur-overlay-color (colors/theme-colors colors/white-70-blur colors/neutral-95-opa-70-blur theme)}
[rn/view {:style style/blur-inner-container}
child]]))
+4 -2
View File
@@ -35,7 +35,9 @@
user-in-syncing-devices-screen? (or (= (:view-id db) :screen/onboarding.syncing-progress)
(= (:view-id db) :screen/profile.profiles)
(= (:view-id db) :screen/onboarding.syncing-progress-intro))
user-in-sign-in-intro-screen? (= (:view-id db) :screen/onboarding.sign-in-intro)]
user-in-sign-in-intro-screen? (= (:view-id db) :screen/onboarding.sign-in-intro)
keystore-files-transfer-action? (= action
constants/local-pairing-action-keystore-files-transfer)]
(merge {:db (cond-> db
connection-success?
(assoc-in [:syncing :pairing-status] :connected)
@@ -61,7 +63,7 @@
(and completed-pairing? receiver?)
{:dispatch [:profile.login/local-paired-user]}
(and error-on-pairing? (some? error))
(and error-on-pairing? (some? error) (not keystore-files-transfer-action?))
{:dispatch [:toasts/upsert
{:type :negative
:text error}]}))))
+5 -1
View File
@@ -25,6 +25,8 @@
(goog-define ALCHEMY_OPTIMISM_GOERLI_TOKEN "")
(goog-define ALCHEMY_OPTIMISM_SEPOLIA_TOKEN "")
(goog-define WALLET_CONNECT_PROJECT_ID "87815d72a81d739d2a7ce15c2cfdefb3")
(goog-define MIXPANEL_APP_ID "3350627")
(goog-define MIXPANEL_TOKEN "5c73bda2d36a9f688a5ee45641fb6775")
(def mainnet-rpc-url (str "https://eth-archival.rpc.grove.city/v1/" POKT_TOKEN))
(def goerli-rpc-url (str "https://goerli-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN))
@@ -39,6 +41,9 @@
(def opensea-link "https://opensea.io")
(def opensea-tesnet-link "https://testnets.opensea.io")
(def mixpanel-app-id MIXPANEL_APP_ID)
(def mixpanel-token MIXPANEL_TOKEN)
(def opensea-api-key OPENSEA_API_KEY)
(def bootnodes-settings-enabled? (enabled? (get-config :BOOTNODES_SETTINGS_ENABLED "1")))
(def mailserver-confirmations-enabled? (enabled? (get-config :MAILSERVER_CONFIRMATIONS_ENABLED)))
@@ -58,7 +63,6 @@
(def quo-preview-enabled? (enabled? (get-config :ENABLE_QUO_PREVIEW "0")))
(def database-management-enabled? (enabled? (get-config :DATABASE_MANAGEMENT_ENABLED "0")))
(def debug-webview? (enabled? (get-config :DEBUG_WEBVIEW "0")))
(def collectibles-enabled? (enabled? (get-config :COLLECTIBLES_ENABLED "1")))
(def test-stateofus? (enabled? (get-config :TEST_STATEOFUS "0")))
(def two-minutes-syncing? (enabled? (get-config :TWO_MINUTES_SYNCING "0")))
(def swap-enabled? (enabled? (get-config :SWAP_ENABLED "0")))
+6 -1
View File
@@ -281,6 +281,7 @@
(def ^:const wallet-connect-supported-events #{"accountsChanged" "chainChanged"})
(def ^:const wallet-connect-session-proposal-event "session_proposal")
(def ^:const wallet-connect-session-request-event "session_request")
(def ^:const wallet-connect-user-rejected-error-key "USER_REJECTED")
(def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer")
@@ -369,16 +370,18 @@
(def ^:const local-pairing-role-receiver "receiver")
;; sender and receiver events
(def ^:const local-pairing-event-peer-discovered "peer-discovered")
(def ^:const local-pairing-event-connection-success "connection-success")
(def ^:const local-pairing-event-connection-error "connection-error")
(def ^:const local-pairing-event-transfer-success "transfer-success")
(def ^:const local-pairing-event-transfer-error "transfer-error")
(def ^:const local-pairing-event-received-installation "received-installation")
;; receiver events
(def ^:const local-pairing-event-received-account "received-account")
(def ^:const local-pairing-event-process-success "process-success")
(def ^:const local-pairing-event-process-error "process-error")
(def ^:const local-pairing-event-received-installation "received-installation")
(def ^:const local-pairing-event-received-keystore-files "received-keystore-files")
(def ^:const local-pairing-event-errors
#{local-pairing-event-connection-error
@@ -389,6 +392,8 @@
(def ^:const local-pairing-action-pairing-account 2)
(def ^:const local-pairing-action-sync-device 3)
(def ^:const local-pairing-action-pairing-installation 4)
(def ^:const local-pairing-action-peer-discovery 5)
(def ^:const local-pairing-action-keystore-files-transfer 6)
(def ^:const serialization-key
"We pass this serialization key as a parameter to MultiformatSerializePublicKey
@@ -0,0 +1,9 @@
(ns status-im.contexts.centralized-metrics.effects
(:require
[native-module.core :as native-module]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.centralized-metrics/toggle-metrics
(fn [enabled?]
(native-module/toggle-centralized-metrics enabled? #(log/debug "toggled-metrics" % enabled?))))
@@ -0,0 +1,33 @@
(ns status-im.contexts.centralized-metrics.events
(:require
[native-module.core :as native-module]
[re-frame.interceptor :as interceptor]
status-im.contexts.centralized-metrics.effects
[status-im.contexts.centralized-metrics.tracking :as tracking]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(defn push-event?
[db]
(or (not (:centralized-metrics/user-confirmed? db))
(:centralized-metrics/enabled? db)))
(defn centralized-metrics-interceptor
[context]
(when-let [event (tracking/tracked-event (interceptor/get-coeffect context :event))]
(log/debug "tracking event" event)
(when (push-event? (interceptor/get-coeffect context :db))
(native-module/add-centralized-metric event)))
context)
(def interceptor
(interceptor/->interceptor
:id :centralized-metrics
:after centralized-metrics-interceptor))
(rf/reg-event-fx :centralized-metrics/toggle-centralized-metrics
(fn [{:keys [db]} [enabled?]]
{:fx [[:effects.centralized-metrics/toggle-metrics enabled?]]
:db (assoc db
:centralized-metrics/user-confirmed? true
:centralized-metrics/enabled? enabled?)}))
@@ -0,0 +1,37 @@
(ns status-im.contexts.centralized-metrics.events-test
(:require
[cljs.test :refer-macros [deftest is testing]]
matcher-combinators.test
[status-im.contexts.centralized-metrics.events :as events]
[status-im.contexts.centralized-metrics.tracking :as tracking]
[test-helpers.unit :as h]))
(deftest push-event-test
(testing "returns correct boolean value"
(is (true? (events/push-event? {:centralized-metrics/user-confirmed? false})))
(is (true? (events/push-event? {:centralized-metrics/enabled? true})))
(is (false? (events/push-event? {:centralized-metrics/user-confirmed? true
:centralized-metrics/enabled? false})))))
(deftest centralized-metrics-interceptor-test
(testing "processes context correctly"
(with-redefs [tracking/tracked-event (fn [_] {:metric "mocked-event"})
events/push-event? (fn [_] true)]
(let [context {:coeffects {:event [:some-event]
:db {:centralized-metrics/enabled? true}}}]
(is (= context (events/centralized-metrics-interceptor context)))))))
(h/deftest-event :centralized-metrics/toggle-centralized-metrics
[event-id dispatch]
(testing "toggling value to true"
(let [enabled? true
expected-fxs {:db {:centralized-metrics/user-confirmed? true
:centralized-metrics/enabled? enabled?}
:fx [[:effects.centralized-metrics/toggle-metrics enabled?]]}]
(is (match? expected-fxs (dispatch [event-id enabled?])))))
(testing "toggling value to false"
(let [enabled? false
expected-fxs {:db {:centralized-metrics/user-confirmed? true
:centralized-metrics/enabled? enabled?}
:fx [[:effects.centralized-metrics/toggle-metrics enabled?]]}]
(is (match? expected-fxs (dispatch [event-id enabled?]))))))
@@ -0,0 +1,40 @@
(ns status-im.contexts.centralized-metrics.tracking
(:require
[legacy.status-im.utils.build :as build]
[react-native.platform :as platform]))
(defn user-journey-event
[action]
{:metric
{:eventName "user-journey"
:platform platform/os
:appVersion build/app-short-version
:eventValue {:action action}}})
(def ^:const app-started-event "app-started")
(def ^:const navigate-to-create-profile-event "navigate-to-create-profile")
(def ^:const communities-tab-clicked "communities-tab-clicked")
(def ^:const wallet-tab-clicked "wallet-tab-clicked")
(def ^:const chats-tab-clicked "chats-tab-clicked")
(defn track-view-id-event
[view-id]
(case view-id
:communities-stack (user-journey-event communities-tab-clicked)
:chats-stack (user-journey-event chats-tab-clicked)
:wallet-stack (user-journey-event wallet-tab-clicked)
nil))
(defn tracked-event
[[event-name second-parameter]]
(case event-name
:onboarding/navigate-to-create-profile
(user-journey-event navigate-to-create-profile-event)
:profile/get-profiles-overview-success
(user-journey-event app-started-event)
:set-view-id
(track-view-id-event second-parameter)
nil))
@@ -0,0 +1,35 @@
(ns status-im.contexts.centralized-metrics.tracking-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.utils.build :as build]
[react-native.platform :as platform]
[status-im.contexts.centralized-metrics.tracking :as tracking]))
(deftest user-journey-event-test
(testing "creates correct metric event"
(let [action "some-action"
expected {:metric {:eventName "user-journey"
:platform platform/os
:appVersion build/app-short-version
:eventValue {:action action}}}]
(is (= expected (tracking/user-journey-event action))))))
(deftest track-view-id-event-test
(testing "returns correct event for view-id"
(is (= (tracking/user-journey-event tracking/communities-tab-clicked)
(tracking/track-view-id-event :communities-stack)))
(is (= (tracking/user-journey-event tracking/chats-tab-clicked)
(tracking/track-view-id-event :chats-stack)))
(is (= (tracking/user-journey-event tracking/wallet-tab-clicked)
(tracking/track-view-id-event :wallet-stack)))
(is (nil? (tracking/track-view-id-event :unknown-stack)))))
(deftest tracked-event-test
(testing "returns correct event for given inputs"
(is (= (tracking/user-journey-event tracking/navigate-to-create-profile-event)
(tracking/tracked-event [:onboarding/navigate-to-create-profile])))
(is (= (tracking/user-journey-event tracking/app-started-event)
(tracking/tracked-event [:profile/get-profiles-overview-success])))
(is (= (tracking/track-view-id-event :wallet-stack)
(tracking/tracked-event [:set-view-id :wallet-stack])))
(is (nil? (tracking/tracked-event [:unknown-event])))))
@@ -139,6 +139,7 @@
[id token-gated? intro-message]
[[(when-not token-gated? (view-members id))
(when-not token-gated? (view-rules id intro-message))
(mark-as-read id)
(invite-contacts id)
(when token-gated? (view-token-gating id))
(show-qr id)
@@ -8,6 +8,7 @@
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im.common.scroll-page.view :as scroll-page]
[status-im.config :as config]
[status-im.contexts.communities.actions.community-options.view :as options]
[status-im.contexts.communities.discover.style :as style]
[status-im.feature-flags :as ff]
@@ -76,12 +77,14 @@
:data [{:id :all
:label (i18n/label :t/all)
:accessibility-label :all-communities-tab}
{:id :open
:label (i18n/label :t/open)
:accessibility-label :open-communities-tab}
{:id :gated
:label (i18n/label :t/gated)
:accessibility-label :gated-communities-tab}]}]])
(when config/show-not-implemented-features?
{:id :open
:label (i18n/label :t/open)
:accessibility-label :open-communities-tab})
(when config/show-not-implemented-features?
{:id :gated
:label (i18n/label :t/gated)
:accessibility-label :gated-communities-tab})]}]])
(defn loading-community-item
[_ _ _ {:keys [width]}]
@@ -343,7 +343,7 @@
(when (get-in db [:communities community-id :joined])
[:dispatch
[:activity-center.notifications/dismiss-community-overview community-id]])]}
(when-not (or (= current-view-id :shell) (= current-view-id :communities-stack))
(when-not (#{:shell :communities-stack :discover-communities} current-view-id)
(navigation/pop-to-root :shell-stack))))))
(rf/reg-event-fx :communities/navigate-to-community-overview navigate-to-community-overview)
@@ -72,10 +72,7 @@
(let [insets (safe-area/get-insets)]
[rn/view {:style (style/page-container insets)}
[rn/view {:style style/page-heading}
[quo/page-nav
{:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])}]
[quo/page-nav {:type :no-title :background :blur}]
[page-title]]
[enable-notifications-simple]
[enable-notification-buttons {:insets insets}]]))
@@ -73,7 +73,7 @@
:onboarding/navigated-to-enter-seed-phrase-from-screen
:screen/onboarding.new-to-status)]]
:dispatch-later [{:ms constants/onboarding-generating-keys-animation-duration-ms
:dispatch [:onboarding/navigate-to-identifiers]}]
:dispatch [:init-root :screen/onboarding.enable-notifications]}]
:db (-> db
(dissoc :profile/login)
(dissoc :auth-method)
+14 -15
View File
@@ -28,21 +28,20 @@
(defn create
[]
(let [log-enabled? (boolean (not-empty config/log-level))]
(merge (login)
{:deviceName (native-module/get-installation-name)
:rootDataDir (native-module/backup-disabled-data-dir)
:rootKeystoreDir (native-module/keystore-dir)
:logLevel (when log-enabled? config/log-level)
:logEnabled log-enabled?
:logFilePath (native-module/log-file-directory)
:verifyTransactionURL config/verify-transaction-url
:verifyENSURL config/verify-ens-url
:verifyENSContractAddress config/verify-ens-contract-address
:verifyTransactionChainID config/verify-transaction-chain-id
:wakuV2LightClient false
:previewPrivacy config/blank-preview?
:testNetworksEnabled config/test-networks-enabled?})))
(assoc (login)
:deviceName (native-module/get-installation-name)
:rootDataDir (native-module/backup-disabled-data-dir)
:rootKeystoreDir (native-module/keystore-dir)
:logLevel (when log-enabled? config/log-level)
:logEnabled log-enabled?
:logFilePath (native-module/log-file-directory)
:verifyTransactionURL config/verify-transaction-url
:verifyENSURL config/verify-ens-url
:verifyENSContractAddress config/verify-ens-contract-address
:verifyTransactionChainID config/verify-transaction-chain-id
:wakuV2LightClient true
:previewPrivacy config/blank-preview?
:testNetworksEnabled config/test-networks-enabled?)))
(defn strip-file-prefix
[path]
+35 -18
View File
@@ -1,7 +1,9 @@
(ns status-im.contexts.profile.events
(:require
[legacy.status-im.data-store.settings :as data-store.settings]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[native-module.core :as native-module]
[status-im.config :as config]
[status-im.contexts.profile.edit.accent-colour.events]
[status-im.contexts.profile.edit.bio.events]
[status-im.contexts.profile.edit.header.events]
@@ -27,7 +29,10 @@
(rf/reg-fx
:profile/get-profiles-overview
(fn [callback]
(native-module/open-accounts callback)))
(native-module/initialize-application {:dataDir (native-module/backup-disabled-data-dir)
:mixpanelAppId config/mixpanel-app-id
:mixpanelToken config/mixpanel-token}
callback)))
(rf/reg-event-fx
:profile/profile-selected
@@ -36,23 +41,27 @@
(rf/reg-event-fx
:profile/get-profiles-overview-success
(fn [{:keys [db]} [profiles-overview]]
(if (seq profiles-overview)
(let [profiles (reduce-profiles profiles-overview)
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))]
{:db (if key-uid
(-> db
(assoc :profile/profiles-overview profiles)
(update :profile/login #(select-profile % key-uid)))
db)
:fx [[:dispatch [:init-root :screen/profile.profiles]]
(when key-uid
[:effects.biometric/check-if-available
{:key-uid key-uid
:on-success (fn [auth-method]
(rf/dispatch [:profile.login/check-biometric-success key-uid
auth-method]))}])]})
{:fx [[:dispatch [:init-root :screen/onboarding.intro]]]})))
(fn [{:keys [db]} [{:keys [accounts] {:keys [userConfirmed enabled]} :centralizedMetricsInfo}]]
(let [db-with-settings (assoc db
:centralized-metrics/user-confirmed? userConfirmed
:centralized-metrics/enabled? enabled)]
(if (seq accounts)
(let [profiles (reduce-profiles accounts)
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))]
{:db (if key-uid
(-> db-with-settings
(assoc :profile/profiles-overview profiles)
(update :profile/login #(select-profile % key-uid)))
db-with-settings)
:fx [[:dispatch [:init-root :screen/profile.profiles]]
(when key-uid
[:effects.biometric/check-if-available
{:key-uid key-uid
:on-success (fn [auth-method]
(rf/dispatch [:profile.login/check-biometric-success key-uid
auth-method]))}])]})
{:db db-with-settings
:fx [[:dispatch [:init-root :screen/onboarding.intro]]]}))))
(rf/reg-event-fx
:profile/update-setting-from-backup
@@ -65,3 +74,11 @@
:profile/update-profile-from-backup
(fn [_ [{{:keys [ensUsernameDetails]} :backedUpProfile}]]
{:fx [[:dispatch [:ens/update-usernames ensUsernameDetails]]]}))
(rf/reg-event-fx :profile/update-messages-from-contacts-only
(fn [{:keys [db] :as cofx}]
(multiaccounts.update/multiaccount-update
cofx
:messages-from-contacts-only
(not (get-in db [:profile/profile :messages-from-contacts-only]))
{})))
@@ -61,13 +61,12 @@
:image :icon
:blur? true
:action :arrow})]
[(when config/show-not-implemented-features?
{:title (i18n/label :t/privacy-and-security)
:on-press #(rf/dispatch [:open-modal :screen/settings-privacy-and-security])
:image-props :i/privacy
:image :icon
:blur? true
:action :arrow})
[{:title (i18n/label :t/privacy-and-security)
:on-press #(rf/dispatch [:open-modal :screen/settings-privacy-and-security])
:image-props :i/privacy
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/syncing)
:on-press #(rf/dispatch [:open-modal :settings-syncing])
:image-props :i/syncing
@@ -1,11 +1,10 @@
(ns status-im.contexts.profile.settings.screens.messages.view
(:require [quo.core :as quo]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- navigate-back
[]
(rf/dispatch [:navigate-back]))
(:require
[quo.core :as quo]
[react-native.core :as rn]
[utils.i18n :as i18n]
[utils.navigation :as navigation]
[utils.re-frame :as rf]))
(defn- open-blocked-users
[]
@@ -13,17 +12,27 @@
(defn view
[]
[quo/overlay {:type :shell :top-inset? true}
[quo/page-nav
{:background :blur
:icon-name :i/arrow-left
:on-press navigate-back}]
[quo/page-top {:title (i18n/label :t/messages)}]
[quo/category
{:label (i18n/label :t/contacts)
:data [{:title (i18n/label :t/blocked-users)
:on-press open-blocked-users
:blur? true
:action :arrow}]
:blur? true
:list-type :settings}]])
(let [allow-new-contact-requests? (rf/sub [:profile/allow-new-contact-requests?])
toggle-allow-new-contact-requests (rn/use-callback
(fn []
(rf/dispatch [:profile/update-messages-from-contacts-only]))
[allow-new-contact-requests?])]
[quo/overlay {:type :shell :top-inset? true}
[quo/page-nav
{:background :blur
:icon-name :i/arrow-left
:on-press navigation/navigate-back}]
[quo/page-top {:title (i18n/label :t/messages)}]
[quo/category
{:label (i18n/label :t/contacts)
:data [{:title (i18n/label :t/allow-new-contact-requests)
:blur? true
:action :selector
:action-props {:on-change toggle-allow-new-contact-requests
:checked? allow-new-contact-requests?}}
{:title (i18n/label :t/blocked-users)
:on-press open-blocked-users
:blur? true
:action :arrow}]
:blur? true
:list-type :settings}]]))
@@ -79,7 +79,7 @@
profile)}}])}]}]]
[rn/flat-list
{:header [settings.header/view {:scroll-y scroll-y}]
:data (settings.items/items (boolean (:mnemonic profile)))
:data (settings.items/items (boolean (seq (:mnemonic profile))))
:shows-vertical-scroll-indicator false
:render-fn settings-category-view
:get-item-layout get-item-layout
@@ -0,0 +1,118 @@
(ns status-im.contexts.settings.privacy-and-security.profile-picture.view
(:require
[quo.core :as quo]
[quo.theme]
[status-im.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def pictures-visibility->label
{constants/profile-pictures-visibility-everyone (i18n/label :t/everyone)
constants/profile-pictures-visibility-contacts-only (i18n/label :t/contacts)
constants/profile-pictures-visibility-none (i18n/label :t/no-one)})
(def pictures-show-to->label
{constants/profile-pictures-show-to-everyone (i18n/label :t/everyone)
constants/profile-pictures-show-to-contacts-only (i18n/label :t/contacts)
constants/profile-pictures-show-to-none (i18n/label :t/no-one)})
(defn- update-profile
[k v]
(rf/dispatch [:profile.settings/profile-update k v])
(rf/dispatch [:hide-bottom-sheet]))
(defn- update-pictures-visibility-everyone
[]
(update-profile :profile-pictures-visibility constants/profile-pictures-visibility-everyone))
(defn- update-pictures-visibility-contacts-only
[]
(update-profile :profile-pictures-visibility constants/profile-pictures-visibility-contacts-only))
(defn- update-pictures-visibility-nobody
[]
(update-profile :profile-pictures-visibility constants/profile-pictures-visibility-none))
(defn- update-pictures-show-to-everyone
[]
(update-profile :profile-pictures-show-to constants/profile-pictures-show-to-everyone))
(defn- update-pictures-show-to-contacts-only
[]
(update-profile :profile-pictures-show-to constants/profile-pictures-show-to-contacts-only))
(defn- update-pictures-show-to-nobody
[]
(update-profile :profile-pictures-show-to constants/profile-pictures-show-to-none))
(defn options-for-profile-pictures-visibility
[setting]
(let [customization-color (rf/sub [:profile/customization-color])]
[:<>
[quo/drawer-top {:title (i18n/label :t/show-profile-pictures)}]
[quo/action-drawer
[[{:icon :i/globe
:accessibility-label :see-profile-pictures-from-everyone
:label (i18n/label :t/everyone)
:on-press update-pictures-visibility-everyone
:state (when (= constants/profile-pictures-visibility-everyone setting)
:selected)}
{:icon :i/contact
:icon-color customization-color
:accessibility-label :see-profile-pictures-from-contacts
:label (i18n/label :t/contacts)
:on-press update-pictures-visibility-contacts-only
:state (when (= constants/profile-pictures-visibility-contacts-only setting)
:selected)}
{:icon :i/hide
:accessibility-label :see-profile-pictures-from-nobody
:label (i18n/label :t/no-one)
:add-divider? true
:on-press update-pictures-visibility-nobody
:state (when (= constants/profile-pictures-visibility-none setting)
:selected)}]]]]))
(defn options-for-profile-pictures-show-to
[setting]
(let [customization-color (rf/sub [:profile/customization-color])]
[:<>
[quo/drawer-top {:title (i18n/label :t/show-profile-pictures-to)}]
[quo/action-drawer
[[{:icon :i/globe
:accessibility-label :show-profile-pictures-to-everyone
:label (i18n/label :t/everyone)
:on-press update-pictures-show-to-everyone
:state (when (= constants/profile-pictures-show-to-everyone setting)
:selected)}
{:icon :i/contact
:icon-color customization-color
:accessibility-label :show-profile-pictures-to-contacts
:label (i18n/label :t/contacts)
:on-press update-pictures-show-to-contacts-only
:state (when (= constants/profile-pictures-show-to-contacts-only setting)
:selected)}
{:icon :i/hide
:accessibility-label :show-profile-pictures-to-nobody
:label (i18n/label :t/no-one)
:on-press update-pictures-show-to-nobody
:state (when (= constants/profile-pictures-show-to-none setting)
:selected)
:add-divider? true}]]]]))
(defn setting-profile-pictures-visibility
[pictures-visibility on-press]
{:title (i18n/label :t/show-profile-pictures)
:description :text
:description-props {:text (pictures-visibility->label pictures-visibility)}
:blur? true
:action :arrow
:on-press on-press})
(defn setting-profile-pictures-show-to
[pictures-show-to on-press]
{:title (i18n/label :t/show-profile-pictures-to)
:description :text
:description-props {:text (pictures-show-to->label pictures-show-to)}
:blur? true
:action :arrow
:on-press on-press})
@@ -2,19 +2,65 @@
(:require
[quo.core :as quo]
[quo.theme]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.safe-area :as safe-area]
[status-im.contexts.settings.privacy-and-security.profile-picture.view :as profile-picture.view]
[status-im.contexts.settings.privacy-and-security.style :as style]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.navigation :as navigation]
[utils.re-frame :as rf]))
(defn navigate-back
[]
(rf/dispatch [:navigate-back]))
(defn- setting-preview-privacy
[preview-privacy? customization-color on-change]
{:title (i18n/label (if platform/android?
:t/hide-content-when-switching-apps
:t/hide-content-when-switching-apps-ios))
:blur? true
:action :selector
:action-props {:on-change on-change
:checked? preview-privacy?
:id :preview-privacy
:customization-color customization-color}})
(defn view
[]
(let [insets (safe-area/get-insets)
customization-color (rf/sub [:profile/customization-color])]
(let [insets (safe-area/get-insets)
centralized-metrics-enabled? (rf/sub [:centralized-metrics/enabled?])
customization-color (rf/sub [:profile/customization-color])
preview-privacy? (rf/sub [:profile/preview-privacy?])
see-profile-pictures-from (rf/sub [:profile/pictures-visibility])
show-profile-pictures-to (rf/sub [:multiaccount/profile-pictures-show-to])
toggle-preview-privacy
(rn/use-callback (fn []
(rf/dispatch [:profile.settings/change-preview-privacy
(not preview-privacy?)]))
[preview-privacy?])
open-see-profile-pictures-from-options
(rn/use-callback (fn []
(rf/dispatch
[:show-bottom-sheet
{:theme :dark
:blur? true
:content (fn []
[profile-picture.view/options-for-profile-pictures-visibility
see-profile-pictures-from])}]))
[see-profile-pictures-from])
open-show-profile-pictures-to-options
(rn/use-callback (fn []
(rf/dispatch
[:show-bottom-sheet
{:theme :dark
:blur? true
:content (fn []
[profile-picture.view/options-for-profile-pictures-show-to
show-profile-pictures-to])}]))
[show-profile-pictures-to])]
[quo/overlay
{:type :shell
:container-style (style/page-wrapper (:top insets))}
@@ -22,7 +68,7 @@
{:key :header
:background :blur
:icon-name :i/arrow-left
:on-press navigate-back}]
:on-press navigation/navigate-back}]
[quo/standard-title
{:title (i18n/label :t/privacy-and-security)
:container-style style/title-container
@@ -30,13 +76,22 @@
:customization-color customization-color}]
[quo/category
{:key :category
:data [{:title "Dummy"
:image-props :i/placeholder
:image :icon
:data [(when (ff/enabled? ::ff/profile-pictures-visibility)
(profile-picture.view/setting-profile-pictures-visibility
see-profile-pictures-from
open-see-profile-pictures-from-options))
(when (ff/enabled? ::ff/profile-pictures-visibility)
(profile-picture.view/setting-profile-pictures-show-to
show-profile-pictures-to
open-show-profile-pictures-to-options))
(setting-preview-privacy preview-privacy? customization-color toggle-preview-privacy)
{:title (i18n/label :t/share-usage-data)
:blur? true
:action :selector
:action-props {:on-change identity
:checked? false}
:on-press identity}]
:action-props {:on-change #(rf/dispatch
[:centralized-metrics/toggle-centralized-metrics
(not centralized-metrics-enabled?)])
:customization-color customization-color
:checked? centralized-metrics-enabled?}}]
:blur? true
:list-type :settings}]]))
@@ -1,5 +1,6 @@
(ns status-im.contexts.settings.wallet.events
(:require
[clojure.string :as string]
[native-module.core :as native-module]
[status-im.contexts.settings.wallet.data-store :as data-store]
[taoensso.timbre :as log]
@@ -91,7 +92,37 @@
(rf/reg-event-fx :wallet/make-keypairs-accounts-fully-operable make-keypairs-accounts-fully-operable)
(defn connection-string-for-import-keypair
(rf/reg-event-fx :wallet/connection-string-for-import-keypairs-failed
(fn [{:keys [db]} [keypairs-key-uids error]]
(let [error-message (-> error ex-data :error)
incorrect-keypair? (string/includes?
error-message
"one or more expected keystore files are not found among the sent files")
single-keypair-to-update? (= (count keypairs-key-uids) 1)
keypair-name (when single-keypair-to-update?
(let [key-uid (first keypairs-key-uids)]
(get-in db [:wallet :keypairs key-uid :name])))
toast-message (cond
(and single-keypair-to-update? incorrect-keypair?)
(i18n/label
:t/this-qr-does-not-contain-key-pair
{:name keypair-name})
(and (not single-keypair-to-update?) incorrect-keypair?)
(i18n/label
:t/this-qr-does-not-contain-any-missing-key-pair)
:else
error-message)]
(log/error "failed to import missing key pairs with connection string"
{:error error-message})
(rf/dispatch [:toasts/upsert
{:type :negative
:theme :dark
:text toast-message}]))))
(defn connection-string-for-import-keypairs
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string]}]]
(let [key-uid (get-in db [:profile/profile :key-uid])]
{:fx [[:effects.syncing/import-keypairs-keystores
@@ -102,14 +133,11 @@
:on-success (fn [key-uids]
(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable key-uids]))
:on-fail (fn [error]
(log/error "failed to import missing key pairs with connection string"
{:error error})
(rf/dispatch [:toasts/upsert
{:type :negative
:theme :dark
:text (i18n/label :t/incorrect-qr-code)}]))}]]}))
(rf/dispatch [:wallet/connection-string-for-import-keypairs-failed
keypairs-key-uids
error]))}]]}))
(rf/reg-event-fx :wallet/connection-string-for-import-keypair connection-string-for-import-keypair)
(rf/reg-event-fx :wallet/connection-string-for-import-keypairs connection-string-for-import-keypairs)
(defn success-keypair-qr-scan
[_ [connection-string keypairs-key-uids]]
@@ -121,7 +149,7 @@
:on-auth-success (fn [password]
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch
[:wallet/connection-string-for-import-keypair
[:wallet/connection-string-for-import-keypairs
{:connection-string connection-string
:keypairs-key-uids keypairs-key-uids
:sha3-pwd password}]))}]]]})
@@ -83,11 +83,11 @@
:on-success fn?
:on-fail fn?}]]}]
(is (match? expected
(sut/connection-string-for-import-keypair cofx
[{:sha3-pwd sha3-pwd
:keypairs-key-uids [test-keypair-key-uid]
:connection-string
connection-string}])))))
(sut/connection-string-for-import-keypairs cofx
[{:sha3-pwd sha3-pwd
:keypairs-key-uids [test-keypair-key-uid]
:connection-string
connection-string}])))))
(deftest success-keypair-qr-scan-test
(let [connection-string "valid-connection-string"
@@ -44,7 +44,7 @@
[{:blur? true
:icon :i/qr-code
:accessibility-label :show-key-pr-qr
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
:label (i18n/label :t/show-encrypted-qr-of-key-pair)
:on-press on-show-qr}]
[{:blur? true
:icon :i/scan
@@ -163,9 +163,8 @@
(rf/dispatch
[:open-modal :screen/settings.save-address]))
[address ens-name? address-or-ens])]
(rn/use-mount (fn []
(rf/dispatch [:wallet/clean-scanned-address])
(rf/dispatch [:wallet/clear-address-to-save])))
(rn/use-unmount #(rf/dispatch [:wallet/clean-scanned-address]))
(rn/use-mount #(rf/dispatch [:wallet/clear-address-to-save]))
[quo/overlay {:type :shell}
[floating-button-page/view
{:footer-container-padding 0
+9 -5
View File
@@ -1,15 +1,19 @@
(ns status-im.contexts.syncing.utils
(:require
[clojure.string :as string]
[status-im.constants :as constants]
[native-module.core :as native-module]
[utils.transforms :as transforms]))
(defn validate-connection-string
[connection-string]
(native-module/validate-connection-string
connection-string))
(defn valid-connection-string?
[connection-string]
(when connection-string
(string/starts-with?
connection-string
constants/local-pairing-connection-string-identifier)))
(some-> connection-string
validate-connection-string
string/blank?))
(defn extract-error
[json-str]
@@ -71,7 +71,7 @@
(rf/reg-event-fx :wallet/seed-phrase-entered seed-phrase-entered)
(defn store-account-generated
(defn store-account-generated-with-mnemonic
[{:keys [db]} [{:keys [new-account-data keypair-name]}]]
(let [new-account (update new-account-data :mnemonic security/mask-data)]
{:db (-> db
@@ -85,20 +85,21 @@
:random-phrase))
:fx [[:dispatch [:navigate-back-to :screen/wallet.create-account]]]}))
(rf/reg-event-fx :wallet/store-account-generated store-account-generated)
(rf/reg-event-fx :wallet/store-account-generated-with-mnemonic store-account-generated-with-mnemonic)
(defn generate-account-for-keypair
(defn generate-account-for-keypair-with-mnemonic
[{:keys [db]} [{:keys [keypair-name]}]]
(let [seed-phrase (-> db :wallet :ui :create-account :new-keypair :seed-phrase)]
{:fx [[:effects.wallet/create-account-from-mnemonic
{:mnemonic-phrase (security/safe-unmask-data seed-phrase)
:paths [constants/path-default-wallet]
:on-success (fn [new-account-data]
(rf/dispatch [:wallet/store-account-generated
(rf/dispatch [:wallet/store-account-generated-with-mnemonic
{:new-account-data new-account-data
:keypair-name keypair-name}]))}]]}))
(rf/reg-event-fx :wallet/generate-account-for-keypair generate-account-for-keypair)
(rf/reg-event-fx :wallet/generate-account-for-keypair-with-mnemonic
generate-account-for-keypair-with-mnemonic)
(defn clear-create-account-data
[{:keys [db]}]
@@ -159,14 +160,19 @@
(rf/reg-event-fx
:wallet/create-keypair-with-account
(fn [{db :db} [password account-preferences]]
(let [{:keys [keypair-name
(let [{:keys [workflow
keypair-name
new-account-data]} (-> db :wallet :ui :create-account :new-keypair)
keypair-type (if (= workflow :workflow/new-keypair.import-private-key)
:key
:seed)
keypair-with-account (create-account.utils/prepare-new-account
{:keypair-name keypair-name
:keypair-type keypair-type
:account-data new-account-data
:account-preferences account-preferences})
new-address (some-> new-account-data
(create-account.utils/first-derived-account)
(create-account.utils/first-derived-account keypair-type)
(:address)
(string/lower-case))
unmasked-password (security/safe-unmask-data password)]
@@ -176,7 +182,7 @@
:on-success [:wallet/add-account-success new-address]
:on-error #(log/error "Failed to add Keypair and create account" %)}]]]})))
(defn import-and-create-keypair-with-account
(defn import-mnemonic-and-create-keypair-with-account
[{db :db} [{:keys [password account-preferences]}]]
(let [account-data (-> db :wallet :ui :create-account :new-keypair :new-account-data)
unmasked-mnemonic (security/safe-unmask-data (:mnemonic account-data))
@@ -187,7 +193,8 @@
:on-success #(rf/dispatch
[:wallet/create-keypair-with-account password account-preferences])}]]]}))
(rf/reg-event-fx :wallet/import-and-create-keypair-with-account import-and-create-keypair-with-account)
(rf/reg-event-fx :wallet/import-mnemonic-and-create-keypair-with-account
import-mnemonic-and-create-keypair-with-account)
(rf/reg-event-fx
:wallet/derive-address-and-add-account
@@ -206,3 +213,49 @@
:on-error [:wallet/log-rpc-error
{:event :wallet/derive-address-and-add-account
:params [derived-from-address [derivation-path]]}]}]]]}))
(defn import-private-key-and-create-keypair-with-account
[{:keys [db]} [{:keys [password account-preferences]}]]
(let [private-key (get-in db
[:wallet :ui :create-account :new-keypair
:new-account-data :private-key])
unmasked-private-key (security/safe-unmask-data private-key)
unmasked-password (security/safe-unmask-data password)]
{:json-rpc/call
[{:method "accounts_importPrivateKey"
:params [unmasked-private-key unmasked-password]
:on-success [:wallet/create-keypair-with-account password account-preferences]
:on-error #(log/error "Failed to import private key" %)}]}))
(rf/reg-event-fx
:wallet/import-private-key-and-create-keypair-with-account
import-private-key-and-create-keypair-with-account)
(defn store-account-generated-with-private-key
[{:keys [db]} [{:keys [new-account-data keypair-name]}]]
{:db (-> db
(update-in [:wallet :ui :create-account :new-keypair]
assoc
:new-account-data new-account-data
:keypair-name keypair-name)
(update-in [:wallet :ui :create-account :new-keypair]
dissoc
:private-key))
:fx [[:dispatch [:navigate-back-to :screen/wallet.create-account]]]})
(rf/reg-event-fx :wallet/store-account-generated-with-private-key
store-account-generated-with-private-key)
(rf/reg-event-fx
:wallet/import-private-key-and-generate-account-for-keypair
(fn [{:keys [db]} [{:keys [keypair-name]}]]
(let [private-key (get-in db [:wallet :ui :create-account :private-key])]
{:db (assoc-in db
[:wallet :ui :create-account :new-keypair :workflow]
:workflow/new-keypair.import-private-key)
:fx [[:effects.wallet/create-account-from-private-key
{:private-key private-key
:on-success (fn [new-account-data]
(rf/dispatch [:wallet/store-account-generated-with-private-key
{:keypair-name keypair-name
:new-account-data new-account-data}]))}]]})))
@@ -37,7 +37,7 @@
{:new-account-data {"test" "data"
:mnemonic masked-mnemonic}
:keypair-name "new-keypair-name"}}}}}
effects (events/store-account-generated {:db db} props)
effects (events/store-account-generated-with-mnemonic {:db db} props)
result-db (:db effects)
remove-mnemonic #(update-in %
[:wallet :ui :create-account :new-keypair :new-account-data]
@@ -61,7 +61,7 @@
expected-effects [[:effects.wallet/create-account-from-mnemonic
{:mnemonic-phrase "test-secret"
:paths [constants/path-default-wallet]}]]
effects (events/generate-account-for-keypair {:db db} props)]
effects (events/generate-account-for-keypair-with-mnemonic {:db db} props)]
(is (match?
(update-in effects [:fx 0 1] dissoc :on-success)
{:fx expected-effects}))
@@ -63,31 +63,31 @@
(let [{:keys [message] :as props}
(case state
:scanning
{:type :info
{:status :default
:icon :i/scanning
:message :t/scanning-for-activity}
:inactive-address
{:type :warning
{:status :warning
:icon :i/info
:message :t/this-account-has-no-activity}
:active-address
{:type :success
{:status :success
:icon :i/done
:message :t/this-address-has-activity}
:invalid-private-key
{:type :error
{:status :error
:icon :i/info
:message :t/invalid-private-key}
nil)]
(when props
[quo/info-message
(assoc props
:size :default
:style style/indicator)
(-> props
(assoc :size :default :container-style style/indicator)
(dissoc :message))
(i18n/label message)])))
(defn on-unmount
@@ -4,7 +4,6 @@
[quo.core :as quo]
[react-native.core :as rn]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.common.not-implemented :as not-implemented]
[status-im.common.validation.general :as validators]
[status-im.constants :as constants]
[status-im.contexts.wallet.add-account.create-account.key-pair-name.style :as style]
@@ -25,12 +24,12 @@
(defn- next-workflow-step
[workflow key-pair-name]
(case workflow
;; TODO issue #19759. Implement creation account from private key
:import-private-key
(not-implemented/alert)
(rf/dispatch [:wallet/import-private-key-and-generate-account-for-keypair
{:keypair-name key-pair-name}])
(:new-keypair :recovery-phrase)
(rf/dispatch [:wallet/generate-account-for-keypair
(rf/dispatch [:wallet/generate-account-for-keypair-with-mnemonic
{:keypair-name key-pair-name}])
(do
@@ -2,28 +2,57 @@
(:require [status-im.constants :as constants]))
(defn first-derived-account
[account-data]
(-> account-data :derived first val))
[account-data keypair-type]
(if (= keypair-type :seed)
(some-> account-data
:derived
first
val)
account-data))
(defn get-account-details
[keypair-type account account-to-create]
(if (= keypair-type :key)
{:key-uid (:key-uid account)
:public-key (:public-key account)
:account-address (:address account)}
{:key-uid (:keyUid account)
:public-key (:publicKey account-to-create)
:account-address (:address account-to-create)}))
(defn get-account-config
[{:keys [account-address key-uid keypair-type public-key account-name emoji color]}]
{:address account-address
:key-uid key-uid
:wallet false
:chat false
:type keypair-type
:path constants/path-default-wallet
:public-key public-key
:name account-name
:emoji emoji
:colorID color
:hidden false})
(defn prepare-new-account
[{keypair-name :keypair-name
{:keys [keyUid address] :as account} :account-data
{:keys [account-name color emoji]} :account-preferences}]
(let [account-to-create (first-derived-account account)
account-config {:address (:address account-to-create)
:key-uid keyUid
:wallet false
:chat false
:type :seed
:path constants/path-default-wallet
:public-key (:publicKey account-to-create)
:name account-name
:emoji emoji
:colorID color
:hidden false}]
{:key-uid keyUid
[{:keys [keypair-name keypair-type]
{:keys [address] :as account} :account-data
{:keys [account-name color emoji]} :account-preferences}]
(let [account-to-create (first-derived-account account keypair-type)
{:keys [key-uid public-key account-address]} (get-account-details keypair-type
account
account-to-create)
account-config (get-account-config {:account-address
account-address
:key-uid key-uid
:keypair-type keypair-type
:public-key public-key
:account-name account-name
:emoji emoji
:color color})]
{:key-uid key-uid
:name keypair-name
:type :seed
:type keypair-type
:derived-from address
:last-used-derivation-index 0
:accounts [account-config]}))
@@ -22,37 +22,38 @@
(defn- get-keypair-data
[{:keys [title primary-keypair? new-keypair? derivation-path customization-color]}]
(let [formatted-path (string/replace derivation-path #"/" " / ")
on-auth-success (fn [password]
(rf/dispatch [:navigate-to
:screen/wallet.edit-derivation-path
{:password password
:current-derivation-path formatted-path}]))]
[{:title title
:image (if primary-keypair? :avatar :icon)
:image-props (if primary-keypair?
{:full-name (utils.string/get-initials title 1)
:size :xxs
:customization-color customization-color}
:i/seed)
:action (when-not new-keypair? :button)
:action-props {:on-press #(rf/dispatch [:navigate-to :screen/wallet.select-keypair])
:button-text (i18n/label :t/edit)
:alignment :flex-start}
:description :text
:description-props {:text (i18n/label :t/on-device)}}
{:title (i18n/label :t/derivation-path)
:image :icon
:image-props :i/derivated-path
:action (if (ff/enabled? ::ff/wallet.edit-derivation-path) :button :none)
:action-props {:on-press #(rf/dispatch [:standard-auth/authorize
{:on-auth-success on-auth-success
:auth-button-label (i18n/label :t/continue)}])
:button-text (i18n/label :t/edit)
:icon-left :i/face-id
:alignment :flex-start}
:description :text
:description-props {:text formatted-path}}]))
[{:title title
:image (if primary-keypair? :avatar :icon)
:image-props (if primary-keypair?
{:full-name (utils.string/get-initials title 1)
:size :xxs
:customization-color customization-color}
:i/seed)
:action (when-not new-keypair? :button)
:action-props {:on-press #(rf/dispatch [:navigate-to :screen/wallet.select-keypair])
:button-text (i18n/label :t/edit)
:alignment :flex-start}
:description :text
:description-props {:text (i18n/label :t/on-device)}}
(when-not (string/blank? derivation-path)
(let [formatted-path (string/replace derivation-path #"/" " / ")
on-auth-success (fn [password]
(rf/dispatch [:navigate-to
:screen/wallet.edit-derivation-path
{:password password
:current-derivation-path formatted-path}]))]
{:title (i18n/label :t/derivation-path)
:image :icon
:image-props :i/derivated-path
:action (if (ff/enabled? ::ff/wallet.edit-derivation-path) :button :none)
:action-props {:on-press #(rf/dispatch [:standard-auth/authorize
{:on-auth-success on-auth-success
:auth-button-label (i18n/label :t/continue)}])
:button-text (i18n/label :t/edit)
:icon-left :i/face-id
:alignment :flex-start}
:description :text
:description-props {:text formatted-path}}))])
(defn- avatar
[{:keys [account-color emoji on-select-emoji]}]
@@ -167,38 +168,59 @@
:container-style (style/slide-button-container bottom))]}]
children))))
(defn- on-auth-success-mnemonic
[password account-preferences]
(rf/dispatch
[:wallet/import-mnemonic-and-create-keypair-with-account
{:password password
:account-preferences account-preferences}]))
(defn- on-auth-success-import-private-key
[password account-preferences]
(rf/dispatch
[:wallet/import-private-key-and-create-keypair-with-account
{:password password
:account-preferences account-preferences}]))
(defn add-new-keypair-variant
[{{:keys [account-name account-color emoji]} :state}]
(let [on-auth-success (fn [password]
(rf/dispatch
[:wallet/import-and-create-keypair-with-account
{:password password
:account-preferences {:account-name @account-name
:color @account-color
:emoji @emoji}}]))]
(fn [{:keys [on-change-text set-account-color set-emoji customization-color keypair-name error]}]
(let [{:keys [new-account-data]} (rf/sub [:wallet/create-account-new-keypair])]
[floating-button
{:account-color @account-color
:slide-button-props {:on-auth-success on-auth-success
:disabled? (empty? @account-name)
:dependencies [new-account-data]}}
[avatar
{:account-color @account-color
:emoji @emoji
:on-select-emoji set-emoji}]
[input
{:account-color @account-color
:account-name @account-name
:on-change-text on-change-text
:error error}]
[color-picker
{:account-color @account-color
:set-account-color set-account-color}]
[new-account-origin
{:derivation-path constants/path-default-wallet
:customization-color customization-color
:keypair-title keypair-name}]]))))
(fn [{:keys [on-change-text set-account-color set-emoji customization-color keypair-name error]}]
(let [{:keys [new-account-data workflow]} (rf/sub [:wallet/create-account-new-keypair])
derivation-path (when (not= workflow
:workflow/new-keypair.import-private-key)
constants/path-default-wallet)]
[floating-button
{:account-color @account-color
:slide-button-props {:on-auth-success (fn on-auth-success [password]
(let [account-preferences {:account-name @account-name
:color @account-color
:emoji @emoji}]
(if (= workflow
:workflow/new-keypair.import-private-key)
(on-auth-success-import-private-key
password
account-preferences)
(on-auth-success-mnemonic
password
account-preferences))))
:disabled? (empty? @account-name)
:dependencies [new-account-data]}}
[avatar
{:account-color @account-color
:emoji @emoji
:on-select-emoji set-emoji}]
[input
{:account-color @account-color
:account-name @account-name
:on-change-text on-change-text
:error error}]
[color-picker
{:account-color @account-color
:set-account-color set-account-color}]
[new-account-origin
{:derivation-path derivation-path
:customization-color customization-color
:keypair-title keypair-name}]])))
(defn derive-account-variant
[{{:keys [account-name account-color emoji]} :state}]
@@ -262,33 +284,33 @@
:account-name-error account-name-error
:emoji-and-color-error? emoji-and-color-error?}]
(fn []
(let [customization-color (rf/sub [:profile/customization-color])
(let [customization-color (rf/sub [:profile/customization-color])
;; Having a keypair means the user is importing it or creating it.
{:keys [keypair-name]} (rf/sub [:wallet/create-account-new-keypair])
accounts-names (rf/sub [:wallet/accounts-names])
accounts-emojis-and-colors (rf/sub [:wallet/accounts-emojis-and-colors])
on-change-text (rn/use-callback
(fn [new-text]
(reset! account-name new-text)
(reset! account-name-error
(common.utils/get-account-name-error new-text
accounts-names)))
[accounts-names accounts-emojis-and-colors])
check-emoji-and-color-error (fn [emoji color]
(let [repeated? (accounts-emojis-and-colors [emoji color])]
(reset! emoji-and-color-error?
(when repeated? :emoji-and-color))))
set-account-color (rn/use-callback
(fn [new-color]
(reset! account-color new-color)
(check-emoji-and-color-error @emoji new-color))
[accounts-emojis-and-colors @emoji])
set-emoji (rn/use-callback
(fn [new-emoji]
(reset! emoji new-emoji)
(check-emoji-and-color-error new-emoji @account-color))
[accounts-emojis-and-colors @account-color])
error (or @account-name-error @emoji-and-color-error?)]
{:keys [keypair-name workflow]} (rf/sub [:wallet/create-account-new-keypair])
accounts-names (rf/sub [:wallet/accounts-names])
accounts-emojis-and-colors (rf/sub [:wallet/accounts-emojis-and-colors])
on-change-text (rn/use-callback
(fn [new-text]
(reset! account-name new-text)
(reset! account-name-error
(common.utils/get-account-name-error new-text
accounts-names)))
[accounts-names accounts-emojis-and-colors])
check-emoji-and-color-error (fn [emoji color]
(let [repeated? (accounts-emojis-and-colors [emoji color])]
(reset! emoji-and-color-error?
(when repeated? :emoji-and-color))))
set-account-color (rn/use-callback
(fn [new-color]
(reset! account-color new-color)
(check-emoji-and-color-error @emoji new-color))
[accounts-emojis-and-colors @emoji])
set-emoji (rn/use-callback
(fn [new-emoji]
(reset! emoji new-emoji)
(check-emoji-and-color-error new-emoji @account-color))
[accounts-emojis-and-colors @account-color])
error (or @account-name-error @emoji-and-color-error?)]
(rn/use-mount #(check-emoji-and-color-error @emoji @account-color))
(rn/use-unmount #(rf/dispatch [:wallet/clear-create-account]))
@@ -300,8 +322,10 @@
:on-change-text on-change-text
:set-account-color set-account-color
:set-emoji set-emoji
:keypair-name keypair-name
:error error}]
:error error
:workflow workflow}]
[derive-account-variant
{:state state
:customization-color customization-color
@@ -177,7 +177,7 @@
"This function returns token values in the props of token-value (quo) component"
[{:keys [token color currency currency-symbol]}]
(let [balance (calculate-total-token-balance token)
fiat-value (calculate-token-fiat-value
fiat-unformatted-value (calculate-token-fiat-value
{:currency currency
:balance balance
:token token})
@@ -191,7 +191,7 @@
crypto-value (get-standard-crypto-format token balance)
fiat-value (get-standard-fiat-format crypto-value
currency-symbol
fiat-value)]
fiat-unformatted-value)]
{:token (:symbol token)
:token-name (:name token)
:state :default
@@ -201,10 +201,11 @@
(neg? change-pct-24hour) :negative
:else :empty)
:customization-color color
:values {:crypto-value crypto-value
:fiat-value fiat-value
:fiat-change formatted-token-price
:percentage-change percentage-change}}))
:values {:crypto-value crypto-value
:fiat-value fiat-value
:fiat-unformatted-value fiat-unformatted-value
:fiat-change formatted-token-price
:percentage-change percentage-change}}))
(defn get-multichain-address
[networks address]
@@ -298,3 +299,18 @@
(utils.string/contains-emoji? s) :emoji
(existing-account-names s) :existing-name
(utils.string/contains-special-character? s) :special-character))
(defn calculate-and-sort-tokens
[{:keys [tokens color currency currency-symbol]}]
(let [calculate-token (fn [token]
(calculate-token-value {:token token
:color color
:currency currency
:currency-symbol currency-symbol}))
calculated-tokens (map calculate-token tokens)
token-priority {"SNT" 1 "STT" 1 "ETH" 2 "DAI" 3}]
(sort-by (fn [token]
(let [fiat-value (get-in token [:values :fiat-unformatted-value])
priority (get token-priority (:token token) 999)]
[(- fiat-value) priority]))
calculated-tokens)))
@@ -115,3 +115,39 @@
(is (= (utils/prettify-percentage-change 1.113454) "1.11"))
(is (= (utils/prettify-percentage-change -0.35) "0.35"))
(is (= (utils/prettify-percentage-change -0.78234) "0.78"))))
(deftest calculate-and-sort-tokens-test
(testing "calculate-and-sort-tokens function"
(let [mock-color "blue"
mock-currency "USD"
mock-currency-symbol "$"]
(with-redefs [utils/calculate-token-value
(fn [{:keys [token]}]
(case (:symbol token)
"ETH" {:token "ETH" :values {:fiat-unformatted-value 5}}
"DAI" {:token "DAI" :values {:fiat-unformatted-value 10}}
"SNT" {:token "SNT" :values {:fiat-unformatted-value 1}}))]
(testing "Standard case with different fiat-unformatted-values"
(let [mock-tokens [{:symbol "ETH"
:name "Ethereum"
:balances-per-chain {:mock-chain 5}
:decimals 18}
{:symbol "DAI"
:name "Dai"
:balances-per-chain {:mock-chain 10}
:decimals 18}
{:symbol "SNT"
:name "Status Network Token"
:balances-per-chain {:mock-chain 1}
:decimals 18}]
mock-input {:tokens mock-tokens
:color mock-color
:currency mock-currency
:currency-symbol mock-currency-symbol}
sorted-tokens (map :token (utils/calculate-and-sort-tokens mock-input))
expected-order ["DAI" "ETH" "SNT"]]
(is (= expected-order sorted-tokens))))))))
+2 -2
View File
@@ -58,11 +58,11 @@
:emoji-hash emojiHash
:key-uid keyUid
:public-key publicKey
:private-key privateKey})))))
:private-key (security/mask-data privateKey)})))))
(rf/reg-fx
:effects.wallet/create-account-from-private-key
(fn [[private-key on-success on-error]]
(fn [{:keys [private-key on-success on-error]}]
(-> (create-account-from-private-key private-key)
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error)))))
+14 -2
View File
@@ -362,11 +362,19 @@
(rf/reg-event-fx :wallet/address-validation-success
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :search-address :valid-ens-or-address?] true)}))
{:db (update-in db
[:wallet :ui :search-address]
assoc
:valid-ens-or-address? true
:loading? false)}))
(rf/reg-event-fx :wallet/address-validation-failed
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :search-address :valid-ens-or-address?] false)}))
{:db (update-in db
[:wallet :ui :search-address]
assoc
:valid-ens-or-address? false
:loading? false)}))
(rf/reg-event-fx :wallet/clean-local-suggestions
(fn [{:keys [db]}]
@@ -374,6 +382,10 @@
(assoc-in [:wallet :ui :search-address :local-suggestions] [])
(assoc-in [:wallet :ui :search-address :valid-ens-or-address?] false))}))
(rf/reg-event-fx :wallet/searching-address
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :search-address :loading?] true)}))
(rf/reg-event-fx
:wallet/navigate-to-chain-explorer-from-bottom-sheet
(fn [_ [explorer-link address]]
@@ -76,6 +76,7 @@
300)))
:on-change-text (fn [text]
(rf/dispatch [:wallet/clean-local-suggestions])
(rf/dispatch [:wallet/searching-address])
(validate-address text)
(reset! input-value text))
:valid-ens-or-address? valid-ens-or-address?}])))
@@ -182,7 +183,8 @@
input-focused? (reagent/atom false)]
(fn []
(let [selected-tab (or (rf/sub [:wallet/send-tab]) (:id (first tabs-data)))
valid-ens-or-address? (boolean (rf/sub [:wallet/valid-ens-or-address?]))]
valid-ens-or-address? (boolean (rf/sub [:wallet/valid-ens-or-address?]))
searching-address? (rf/sub [:wallet/searching-address?])]
[floating-button-page/view
{:content-container-style {:flex 1}
:footer-container-padding 0
@@ -198,7 +200,7 @@
:title-accessibility-label :title-label}]
[address-input input-value input-focused?]
[quo/divider-line]
(when (and (not valid-ens-or-address?) (> (count @input-value) 0))
(when (and (not valid-ens-or-address?) (> (count @input-value) 0) (not searching-address?))
[rn/view {:style {:padding 20}}
[quo/info-message
{:status :error
@@ -118,12 +118,27 @@
(rf/reg-fx
:effects.wallet-connect/respond-session-request
(fn [{:keys [web3-wallet topic id result on-success on-error]}]
(fn [{:keys [web3-wallet topic id result error on-success on-error]}]
(->
(.respondSessionRequest web3-wallet
(clj->js {:topic topic
:response {:id id
:jsonrpc "2.0"
:result result}}))
:response (merge {:id id
:jsonrpc "2.0"}
(when result
{:result result})
(when error
{:error error}))}))
(promesa/then on-success)
(promesa/catch on-error))))
(rf/reg-fx
:effects.wallet-connect/reject-session-proposal
(fn [{:keys [web3-wallet proposal on-success on-error]}]
(let [{:keys [id]} proposal
reason (wallet-connect/get-sdk-error
constants/wallet-connect-user-rejected-error-key)]
(-> (.rejectSession web3-wallet
(clj->js {:id id
:reason reason}))
(promesa/then on-success)
(promesa/catch on-error)))))
@@ -166,16 +166,10 @@
{:web3-wallet web3-wallet
:proposal current-proposal
:supported-namespaces supported-namespaces
:on-success (fn []
:on-success (fn [approved-session]
(log/info "Wallet Connect session approved")
(let [metadata (wallet-connect-core/get-session-dapp-metadata
current-proposal)]
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
(rf/dispatch [:wallet-connect/persist-session
{:id (:id current-proposal)
:dapp-name (:name metadata)
:dapp-url (:url metadata)
:session-info current-proposal}])))
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
(rf/dispatch [:wallet-connect/persist-session approved-session]))
:on-fail (fn [error]
(log/error "Wallet Connect session approval failed"
{:error error
@@ -210,20 +204,6 @@
{:version version}))}]]]}
{:fx [[:dispatch [:wallet-connect/pair scanned-text]]]}))))
(rf/reg-event-fx
:wallet-connect/persist-session
(fn [_ [{:keys [id dapp-name dapp-url session-info]}]]
{:fx [[:json-rpc/call
[{:method "wakuext_addWalletConnectSession"
:params [{:id (str id)
:dappName dapp-name
:dappUrl dapp-url
:info (-> session-info
clj->js
js/JSON.stringify)}]
:on-success #(log/info "Wallet Connect session persisted")
:on-error #(log/info "Wallet Connect session persistence failed" %)}]]]}))
(rf/reg-event-fx
:wallet-connect/fetch-persisted-sessions-success
(fn [{:keys [db]} [sessions]]
@@ -233,6 +213,18 @@
:wallet-connect/fetch-persisted-sessions
(fn [_ _]
{:fx [[:json-rpc/call
[{:method "wakuext_getWalletConnectSession"
[{:method "wallet_getWalletConnectActiveSessions"
;; This is the activeSince timestamp to avoid expired sessions
;; 0 means, return everything
:params [0]
:on-success [:wallet-connect/fetch-persisted-sessions-success]
:on-error #(log/info "Wallet Connect fetch persisted sessions failed")}]]]}))
:on-error #(log/info "Wallet Connect fetch persisted sessions failed" %)}]]]}))
(rf/reg-event-fx
:wallet-connect/persist-session
(fn [_ [session-info]]
{:fx [[:json-rpc/call
[{:method "wallet_addWalletConnectSession"
:params [(js/JSON.stringify session-info)]
:on-success #(log/info "Wallet Connect session persisted")
:on-error #(log/info "Wallet Connect session persistence failed" %)}]]]}))
@@ -0,0 +1,12 @@
(ns status-im.contexts.wallet.wallet-connect.modals.common.page-nav.view
(:require [quo.core :as quo]
[utils.re-frame :as rf]))
(defn view
[{:keys [accessibility-label]}]
[quo/page-nav
{:icon-name :i/close
:background :blur
:on-press #(do (rf/dispatch [:navigate-back])
(rf/dispatch [:wallet-connect/reject-session-request]))
:accessibility-label accessibility-label}])
@@ -5,6 +5,7 @@
[status-im.contexts.wallet.wallet-connect.modals.common.data-block.view :as data-block]
[status-im.contexts.wallet.wallet-connect.modals.common.footer.view :as footer]
[status-im.contexts.wallet.wallet-connect.modals.common.header.view :as header]
[status-im.contexts.wallet.wallet-connect.modals.common.page-nav.view :as page-nav]
[status-im.contexts.wallet.wallet-connect.modals.common.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -20,11 +21,8 @@
error-state]} (rf/sub [:wallet-connect/current-request-transaction-information])]
[rn/view {:style (style/container bottom)}
[quo/gradient-cover {:customization-color customization-color}]
[quo/page-nav
{:icon-name :i/close
:background :blur
:on-press #(rf/dispatch [:navigate-back])
:accessibility-label :wallet-connect-sign-message-close}]
[page-nav/view
{:accessibility-label :wallet-connect-sign-message-close}]
[rn/view {:flex 1}
[rn/view {:style style/data-content-container}
[header/view
@@ -5,6 +5,7 @@
[status-im.contexts.wallet.wallet-connect.modals.common.data-block.view :as data-block]
[status-im.contexts.wallet.wallet-connect.modals.common.footer.view :as footer]
[status-im.contexts.wallet.wallet-connect.modals.common.header.view :as header]
[status-im.contexts.wallet.wallet-connect.modals.common.page-nav.view :as page-nav]
[status-im.contexts.wallet.wallet-connect.modals.common.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -17,11 +18,8 @@
dapp (rf/sub [:wallet-connect/current-request-dapp])]
[rn/view {:style (style/container bottom)}
[quo/gradient-cover {:customization-color customization-color}]
[quo/page-nav
{:icon-name :i/close
:background :blur
:on-press #(rf/dispatch [:navigate-back])
:accessibility-label :wallet-connect-sign-message-close}]
[page-nav/view
{:accessibility-label :wallet-connect-sign-message-close}]
[rn/view {:flex 1}
[rn/view {:style style/sign-message-content-container}
[header/view
@@ -5,6 +5,7 @@
[status-im.contexts.wallet.wallet-connect.modals.common.data-block.view :as data-block]
[status-im.contexts.wallet.wallet-connect.modals.common.footer.view :as footer]
[status-im.contexts.wallet.wallet-connect.modals.common.header.view :as header]
[status-im.contexts.wallet.wallet-connect.modals.common.page-nav.view :as page-nav]
[status-im.contexts.wallet.wallet-connect.modals.common.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -20,11 +21,8 @@
error-state]} (rf/sub [:wallet-connect/current-request-transaction-information])]
[rn/view {:style (style/container bottom)}
[quo/gradient-cover {:customization-color customization-color}]
[quo/page-nav
{:icon-name :i/close
:background :blur
:on-press #(rf/dispatch [:navigate-back])
:accessibility-label :wallet-connect-sign-message-close}]
[page-nav/view
{:accessibility-label :wallet-connect-sign-message-close}]
[rn/view {:flex 1}
[rn/view {:style style/data-content-container}
[header/view
@@ -1,5 +1,6 @@
(ns status-im.contexts.wallet.wallet-connect.responding-events
(:require [re-frame.core :as rf]
[react-native.wallet-connect :as wallet-connect]
[status-im.constants :as constants]
[status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core]
[taoensso.timbre :as log]))
@@ -37,8 +38,7 @@
:address address
:data raw-data
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/send-response %])}]]})))
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
(rf/reg-event-fx
:wallet-connect/respond-personal-sign
@@ -49,7 +49,7 @@
:address address
:data raw-data
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/send-response %])}]]})))
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-typed-data
@@ -61,7 +61,7 @@
:data raw-data
:version typed-data-version
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/send-response %])}]]})))
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
(rf/reg-event-fx
:wallet-connect/respond-send-transaction-data
@@ -73,7 +73,7 @@
:chain-id chain-id
:tx raw-data
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/send-response %])}]]})))
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-transaction-data
@@ -85,7 +85,7 @@
:chain-id chain-id
:tx raw-data
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/send-response %])}]]})))
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
(rf/reg-event-fx
:wallet-connect/on-sign-error
@@ -104,10 +104,9 @@
{:fx [[:dispatch [:dismiss-modal screen]]
[:dispatch [:wallet-connect/reset-current-request]]]})))
(rf/reg-event-fx
:wallet-connect/send-response
(fn [{:keys [db]} [result]]
(fn [{:keys [db]} [{:keys [result error]}]]
(let [{:keys [id topic] :as event} (get-in db [:wallet-connect/current-request :event])
method (wallet-connect-core/get-request-method event)
screen (wallet-connect-core/method-to-screen method)
@@ -117,6 +116,7 @@
:topic topic
:id id
:result result
:error error
:on-error (fn [error]
(log/error "Failed to send Wallet Connect response"
{:error error
@@ -129,3 +129,28 @@
(log/info "Successfully sent Wallet Connect response to dApp")
(rf/dispatch [:dismiss-modal screen])
(rf/dispatch [:wallet-connect/reset-current-request]))}]]})))
(rf/reg-event-fx
:wallet-connect/reject-session-proposal
(fn [{:keys [db]} _]
(let [web3-wallet (get db :wallet-connect/web3-wallet)
current-proposal (get-in db [:wallet-connect/current-proposal :request])]
{:fx [[:effects.wallet-connect/reject-session-proposal
{:web3-wallet web3-wallet
:proposal current-proposal
:on-success #(log/info "Wallet Connect session proposal rejected")
:on-error #(log/error "Wallet Connect unable to reject session proposal")}]
[:dispatch [:wallet-connect/reset-current-session]]]})))
;; NOTE: Currently we only reject a session if the user rejected it
;; But this needs to be solidified to ensure other cases:
;; - Unsupported WC version
;; - Invalid params from dapps
;; - Unsupported method
(rf/reg-event-fx
:wallet-connect/reject-session-request
(fn [_ _]
{:fx [[:dispatch
[:wallet-connect/send-response
{:error (wallet-connect/get-sdk-error
constants/wallet-connect-user-rejected-error-key)}]]]}))
@@ -142,7 +142,7 @@
:accessibility-label :wc-deny-connection
:on-press #(do (rf/dispatch [:navigate-back])
(rf/dispatch
[:wallet-connect/reset-current-session]))}
[:wallet-connect/reject-session-proposal]))}
:button-one-label (i18n/label :t/connect)
:button-one-props {:customization-color customization-color
:type :primary
+6
View File
@@ -11,6 +11,12 @@
(def ^:private initial-flags
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
;; Feature toggled (off by default) because the desktop app disabled this
;; feature and we want both clients in sync. We keep the code because it
;; works and we may re-enable it by default.
::profile-pictures-visibility (enabled-in-env? :FLAG_PROFILE_PICTURES_VISIBILITY_ENABLED)
::settings.import-all-keypairs (enabled-in-env?
:FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS)
::shell.jump-to (enabled-in-env? :ENABLE_JUMP_TO)
+5 -6
View File
@@ -346,12 +346,11 @@
:component enter-seed-phrase/view}
{:name :screen/onboarding.enable-notifications
:options {:theme :dark
:layout options/onboarding-transparent-layout
:animations (merge
transitions/new-to-status-modal-animations
transitions/push-animations-for-transparent-background)
:modalPresentationStyle :overCurrentContext}
:options {:theme :dark
:layout options/onboarding-transparent-layout
:animations (merge
transitions/new-to-status-modal-animations
transitions/push-animations-for-transparent-background)}
:component enable-notifications/view}
{:name :screen/onboarding.identifiers
+2
View File
@@ -2,11 +2,13 @@
(:require
[re-frame.core :as re-frame]
[re-frame.std-interceptors :as std-interceptors]
[status-im.contexts.centralized-metrics.events :as centralized-metrics]
[utils.re-frame :as rf]))
(defn register-global-interceptors
[]
(re-frame/reg-global-interceptor rf/debug-handlers-names)
(re-frame/reg-global-interceptor centralized-metrics/interceptor)
(re-frame/reg-global-interceptor (re-frame/inject-cofx :now))
;; Interceptor `trim-v` removes the first element of the event vector.
+14
View File
@@ -231,6 +231,20 @@
(fn [multiaccount]
(pos? (count (get multiaccount :images)))))
(re-frame/reg-sub :profile/pictures-visibility
:<- [:profile/profile]
:-> :profile-pictures-visibility)
(re-frame/reg-sub :profile/allow-new-contact-requests?
:<- [:profile/profile]
(fn [{:keys [messages-from-contacts-only]}]
(not messages-from-contacts-only)))
(re-frame/reg-sub :profile/preview-privacy?
:<- [:profile/profile]
(fn [{:keys [preview-privacy?]}]
(boolean preview-privacy?)))
(defn- replace-multiaccount-image-uri
[profile ens-names port font-file avatar-opts theme]
(let [{:keys [key-uid ens-name? images
+4 -3
View File
@@ -91,9 +91,6 @@
(reg-root-key-sub :multiaccount/reset-password-form-vals :multiaccount/reset-password-form-vals)
(reg-root-key-sub :multiaccount/reset-password-errors :multiaccount/reset-password-errors)
(reg-root-key-sub :multiaccount/resetting-password? :multiaccount/resetting-password?)
;;delete profile
(reg-root-key-sub :delete-profile/error :delete-profile/error)
(reg-root-key-sub :delete-profile/keep-keys-on-keycard? :delete-profile/keep-keys-on-keycard?)
;;chat
(reg-root-key-sub :chats/cooldown-enabled? :chat/cooldown-enabled?)
@@ -185,3 +182,7 @@
;;theme
(reg-root-key-sub :theme :theme)
;; centralized-metrics
(reg-root-key-sub :centralized-metrics/enabled? :centralized-metrics/enabled?)
(reg-root-key-sub :centralized-metrics/user-confirmed? :centralized-metrics/user-confirmed?)
+26 -21
View File
@@ -489,19 +489,6 @@
(fn [ui]
(get-in ui [:account-page :active-tab])))
(rf/reg-sub
:wallet/current-viewing-account-token-values
:<- [:wallet/current-viewing-account]
:<- [:wallet/current-viewing-account-tokens-in-selected-networks]
:<- [:profile/currency]
:<- [:profile/currency-symbol]
(fn [[{:keys [color]} tokens currency currency-symbol]]
(mapv #(utils/calculate-token-value {:token %
:color color
:currency currency
:currency-symbol currency-symbol})
tokens)))
(rf/reg-sub
:wallet/aggregated-tokens
:<- [:wallet/accounts-without-watched-accounts]
@@ -515,6 +502,18 @@
(fn [[aggregated-tokens chain-ids]]
(utils/filter-tokens-in-chains aggregated-tokens chain-ids)))
(rf/reg-sub
:wallet/current-viewing-account-token-values
:<- [:wallet/current-viewing-account]
:<- [:wallet/current-viewing-account-tokens-in-selected-networks]
:<- [:profile/currency]
:<- [:profile/currency-symbol]
(fn [[{:keys [color]} tokens currency currency-symbol]]
(utils/calculate-and-sort-tokens {:tokens tokens
:color color
:currency currency
:currency-symbol currency-symbol})))
(rf/reg-sub
:wallet/aggregated-token-values-and-balance
:<- [:wallet/aggregated-tokens-in-selected-networks]
@@ -522,16 +521,17 @@
:<- [:profile/currency]
:<- [:profile/currency-symbol]
(fn [[aggregated-tokens color currency currency-symbol]]
(let [balance (utils/calculate-balance-from-tokens {:currency currency
:tokens aggregated-tokens})
formatted-balance (utils/prettify-balance currency-symbol balance)]
(let [balance (utils/calculate-balance-from-tokens {:currency currency
:tokens aggregated-tokens})
formatted-balance (utils/prettify-balance currency-symbol balance)
sorted-token-values (utils/calculate-and-sort-tokens {:tokens aggregated-tokens
:color color
:currency currency
:currency-symbol currency-symbol})]
{:balance balance
:formatted-balance formatted-balance
:tokens (mapv #(utils/calculate-token-value {:token %
:color color
:currency currency
:currency-symbol currency-symbol})
aggregated-tokens)})))
:tokens sorted-token-values})))
(rf/reg-sub
:wallet/network-preference-details
@@ -595,6 +595,11 @@
:<- [:wallet/search-address]
:-> :valid-ens-or-address?)
(rf/reg-sub
:wallet/searching-address?
:<- [:wallet/search-address]
:-> :loading?)
(rf/reg-sub
:wallet/aggregated-fiat-balance-per-chain
:<- [:wallet/aggregated-tokens]
+6 -3
View File
@@ -65,9 +65,9 @@
(def account-manager
(clj->js
{:openAccounts
(fn [callback]
(callback (.openAccounts native-status test-dir)))
{:initializeApplication
(fn [request callback]
(callback (.initializeApplication native-status request)))
:createAccountAndLogin
(fn [request] (.createAccountAndLogin native-status request))
:restoreAccountAndLogin
@@ -130,6 +130,9 @@
(clj->js
{:getNodeConfig
(fn [] (types/clj->json {:WakuV2Config ""}))
:addCentralizedMetric
(fn [_ callback]
(callback))
:fleets
(fn [] (.fleets native-status))
:startLocalNotifications
+8
View File
@@ -0,0 +1,8 @@
(ns utils.navigation
"Prefer to declare in this namespace only reusable navigation functions that
aren't better suited in a particular bounded context."
(:require [utils.re-frame :as rf]))
(defn navigate-back
[]
(rf/dispatch [:navigate-back]))
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.181.31",
"commit-sha1": "6e056348e6d28f962167118612826f1ef0e47b22",
"src-sha256": "1qvfwk28sg93basjzy8r55qz8pk9xg0h7kxv5ykxkbfh4q17a1ns"
"version": "89e914575a0a0b9663b14678fbec3412aa4b2ea4",
"commit-sha1": "89e914575a0a0b9663b14678fbec3412aa4b2ea4",
"src-sha256": "0ph10465i452msh63mzf4kgpsq4nnksfx38yhs54mfyiswbjks48"
}
+1
View File
@@ -88,6 +88,7 @@ def get_capabilities_sauce_lab():
caps['sauce:options']['name'] = test_suite_data.current_test.name
caps['sauce:options']['maxDuration'] = 3600
caps['sauce:options']['idleTimeout'] = 1000
caps['sauce:options']['android.gpu.mode'] = 'hardware'
options = AppiumOptions()
options.load_capabilities(caps)
@@ -291,7 +291,6 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.errors.append("Status community logo is different from expected template.")
self.community_view.close_community_view_button.click()
self.home.discover_communities_button.click()
self.home.swipe_up()
except TimeoutException:
+6 -6
View File
@@ -244,8 +244,8 @@ class SignInView(BaseView):
self.generate_keys_button.click_until_presence_of_element(self.profile_title_input)
self.set_profile(username)
self.set_password(password)
if self.enable_biometric_maybe_later_button.is_element_displayed(10):
self.enable_biometric_maybe_later_button.click()
# if self.enable_biometric_maybe_later_button.is_element_displayed(10):
# self.enable_biometric_maybe_later_button.click()
# self.next_button.click_until_absense_of_element(self.element_by_translation_id("intro-wizard-title2"))
# if keycard:
# keycard_flow = self.keycard_storage_button.click()
@@ -256,7 +256,7 @@ class SignInView(BaseView):
# self.create_password_input.send_keys(password)
# self.confirm_your_password_input.send_keys(password)
# self.next_button.click()
self.identifiers_button.wait_and_click(30)
# self.identifiers_button.wait_and_click(30)
if enable_notifications:
self.enable_notifications_button.click_until_presence_of_element(self.start_button)
if self.allow_button.is_element_displayed():
@@ -283,9 +283,9 @@ class SignInView(BaseView):
self.continue_button.click_until_presence_of_element(self.profile_title_input)
self.set_profile(username, set_image)
self.set_password(password)
if self.enable_biometric_maybe_later_button.is_element_displayed(10):
self.enable_biometric_maybe_later_button.click()
self.identifiers_button.wait_and_click(30)
# if self.enable_biometric_maybe_later_button.is_element_displayed(10):
# self.enable_biometric_maybe_later_button.click()
# self.identifiers_button.wait_and_click(30)
if enable_notifications:
self.enable_notifications_button.click_until_presence_of_element(self.start_button)
else:
+6 -2
View File
@@ -16,6 +16,7 @@
"added-you-to": "added you to",
"address-name": "Address name",
"anyone": "Anyone",
"allow-new-contact-requests": "Allow new contact requests",
"messages-from-contacts-only-subtitle": "Only people you added as contacts can start a new chat with you or invite you to a group",
"messages-gap-warning": "Some messages might be missing",
"accept-new-chats-from": "Accept new chats from",
@@ -1093,6 +1094,7 @@
"node-version": "Node version",
"nonce": "Nonce",
"none": "None",
"no-one": "No one",
"not-a-chatkey": "This is not a chatkey",
"not-applicable": "Not applicable for unsigned transactions",
"not-keycard-text": "The card you used is not a Keycard. You need to purchase a Keycard to use it",
@@ -1311,7 +1313,8 @@
"scan-key-pairs-qr-code": "Scan key pairs QR code",
"invalid-qr": "Oops! This QR doesnt work with Status",
"invalid-key-pair-qr": "This does not look like a key pair QR code",
"incorrect-qr-code": "This is not the QR code you are looking for",
"this-qr-does-not-contain-key-pair": "This QR does not contain {{name}} key pair",
"this-qr-does-not-contain-any-missing-key-pair": "This QR does not contain any missing key pairs",
"search": "Search",
"search-discover-communities": "Search communities or categories",
"secret-keys-confirmation-text": "You will need them to continue to use your Keycard in case you ever lose your phone.",
@@ -1363,7 +1366,7 @@
"show-more": "Show more",
"show-qr": "Show QR code",
"show-transaction-data": "Show transaction data",
"show-encrypted-qr-of-key-pairs": "Show encrypted QR of key pairs on device",
"show-encrypted-qr-of-key-pair": "Show encrypted QR of key pair",
"sign-and-send": "Sign and send",
"sign-in": "Sign in",
"sign-message": "Sign Message",
@@ -2749,5 +2752,6 @@
"import-keypair-to-use-account": "Import key pair to use this account",
"import-keypair-steps": "{{account-name}} was derived from your {{keypair-name}} key pair, which has not yet been imported to this device. To transact using this account, you will need to import the {{keypair-name}} key pair first.",
"not-now": "Not now",
"share-usage-data": "Share usage data with Status",
"value-higher-than-send-amount": "This value is higher than entered amount to send"
}