From f93e372d18e7948189fbf351b8265860b31a075d Mon Sep 17 00:00:00 2001 From: Lungu Cristian Date: Tue, 25 Jun 2024 15:35:45 +0300 Subject: [PATCH 01/10] Add data-item to `quo/category` (#20542) * feat: added data-item to category quo component * feat: session proposal with data-item & category * test: category with data-items * chore: removed unnecessary -> * fix: trailing newline --- .../settings/category/component_spec.cljs | 21 ++++++ .../settings/category/data_item/view.cljs | 32 ++++++++ .../components/settings/category/view.cljs | 9 ++- .../preview/quo/settings/category.cljs | 30 +++++++- .../session_proposal/style.cljs | 5 -- .../wallet_connect/session_proposal/view.cljs | 74 ++++++++++--------- 6 files changed, 127 insertions(+), 44 deletions(-) create mode 100644 src/quo/components/settings/category/data_item/view.cljs diff --git a/src/quo/components/settings/category/component_spec.cljs b/src/quo/components/settings/category/component_spec.cljs index bba6d0416f..5286935c3e 100644 --- a/src/quo/components/settings/category/component_spec.cljs +++ b/src/quo/components/settings/category/component_spec.cljs @@ -51,3 +51,24 @@ :right-icon :i/globe :chevron? true}]}]) (h/is-truthy (h/get-by-text "subtitle")))) + +(h/describe "Data Item Category tests" + (h/test "category renders" + (h/render [category/category + {:list-type :data-item + :label "Label" + :data [{:title "Item 1" + :subtitle "subtitle" + :right-icon :i/globe}]}]) + (h/is-truthy (h/get-by-text "Label")) + (h/is-truthy (h/get-by-text "Item 1")) + (h/is-truthy (h/get-by-text "subtitle"))) + + (h/test "category renders without label" + (h/render [category/category + {:list-type :data-item + :data [{:title "Item 1" + :subtitle "subtitle" + :right-icon :i/globe}]}]) + (h/is-falsy (h/query-by-label-text "Label")) + (h/is-truthy (h/get-by-text "Item 1")))) diff --git a/src/quo/components/settings/category/data_item/view.cljs b/src/quo/components/settings/category/data_item/view.cljs new file mode 100644 index 0000000000..e83f4966f0 --- /dev/null +++ b/src/quo/components/settings/category/data_item/view.cljs @@ -0,0 +1,32 @@ +(ns quo.components.settings.category.data-item.view + (:require + [quo.components.markdown.text :as text] + [quo.components.settings.category.style :as style] + [quo.components.settings.data-item.view :as data-item] + [quo.theme :as quo.theme] + [react-native.core :as rn])) + +(defn view + [{:keys [label data container-style blur?]}] + (let [theme (quo.theme/use-theme) + last-item (rn/use-memo #(last data) [data])] + [rn/view {:style (merge (style/container label) container-style)} + (when label + [text/text + {:weight :medium + :size :paragraph-2 + :style (style/label blur? theme)} + label]) + [rn/view {:style (style/settings-items blur? theme)} + (for [item data + ;; NOTE: overwriting the background of the data-item in favor of the category bg + :let [data-item-container-style (-> item :container-style (assoc :background-color nil)) + data-item-props (assoc item + :blur? blur? + :container-style data-item-container-style)]] + ^{:key item} + [:<> + [data-item/view data-item-props] + (when-not (= item last-item) + [rn/view {:style (style/settings-separator blur? theme)}])])]])) + diff --git a/src/quo/components/settings/category/view.cljs b/src/quo/components/settings/category/view.cljs index 6fd33ca3fd..a8deab9211 100644 --- a/src/quo/components/settings/category/view.cljs +++ b/src/quo/components/settings/category/view.cljs @@ -1,10 +1,13 @@ (ns quo.components.settings.category.view (:require + [quo.components.settings.category.data-item.view :as data-item] [quo.components.settings.category.reorder.view :as reorder] [quo.components.settings.category.settings.view :as settings])) (defn category [{:keys [list-type] :as props}] - (if (= list-type :settings) - [settings/settings-category props] - [reorder/reorder-category props])) + (condp = list-type + :settings [settings/settings-category props] + :data-item [data-item/view props] + :reorder [reorder/reorder-category props] + nil)) diff --git a/src/status_im/contexts/preview/quo/settings/category.cljs b/src/status_im/contexts/preview/quo/settings/category.cljs index 51986ddf9e..64ce484c56 100644 --- a/src/status_im/contexts/preview/quo/settings/category.cljs +++ b/src/status_im/contexts/preview/quo/settings/category.cljs @@ -1,6 +1,7 @@ (ns status-im.contexts.preview.quo.settings.category (:require [quo.core :as quo] + [quo.foundations.colors :as colors] [reagent.core :as reagent] [status-im.common.resources :as resources] [status-im.contexts.preview.quo.preview :as preview])) @@ -17,6 +18,24 @@ :image-props :i/browser :image-size 32}))) +(defn create-data-item-array + [n] + (vec + (for [i (range n)] + {:blur? false + :description :default + :icon-right? true + :right-icon :i/chevron-right + :icon-color colors/neutral-10 + :card? false + :label :preview + :status :default + :size :default + :right-content {:type :accounts + :data [{:emoji "🔥" :customization-color :yellow}]} + :title (str "Item title " i) + :subtitle "Item subtitle"}))) + (def descriptor [{:key :blur? :type :boolean} {:key :list-type @@ -24,7 +43,11 @@ :options [{:key :settings :value :settings} {:key :reorder - :value :reorder}]}]) + :value :reorder} + {:key :data-item + :value :data-item}]}]) + +(def ^:constant n-items 5) (defn view [] @@ -32,7 +55,10 @@ :blur? false :list-type :settings})] (fn [] - (let [data (create-item-array 5)] + (let [list-type (:list-type @state) + data (if (= list-type :data-item) + (create-data-item-array n-items) + (create-item-array n-items))] [preview/preview-container {:state state :descriptor descriptor diff --git a/src/status_im/contexts/wallet/wallet_connect/session_proposal/style.cljs b/src/status_im/contexts/wallet/wallet_connect/session_proposal/style.cljs index b99de1ef5d..488c180398 100644 --- a/src/status_im/contexts/wallet/wallet_connect/session_proposal/style.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/session_proposal/style.cljs @@ -24,8 +24,3 @@ (def approval-li-spacer {:width 8}) - -(def detail-item - {:margin-bottom 20 - :margin-horizontal 20 - :padding 12}) diff --git a/src/status_im/contexts/wallet/wallet_connect/session_proposal/view.cljs b/src/status_im/contexts/wallet/wallet_connect/session_proposal/view.cljs index c8f9c43971..770037f503 100644 --- a/src/status_im/contexts/wallet/wallet_connect/session_proposal/view.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/session_proposal/view.cljs @@ -2,6 +2,7 @@ (:require [quo.core :as quo] [quo.foundations.colors :as colors] + [quo.foundations.resources :as quo.resources] [quo.theme] [react-native.core :as rn] [status-im.common.floating-button-page.view :as floating-button-page] @@ -44,41 +45,47 @@ [quo/text label]]) labels)])) -(defn- accounts-data-item +(defn- get-placeholder-networks [] - ;; TODO. This account is currently hard coded in - ;; `status-im.contexts.wallet.wallet-connect.events`. Should be selectable and changeable - (let [accounts (rf/sub [:wallet/accounts-without-watched-accounts]) - name (-> accounts first :name)] - [quo/data-item - {:container-style style/detail-item - :blur? false - :description :default - :icon-right? true - :right-icon :i/chevron-right - :icon-color colors/neutral-10 - :card? false - :label :preview - ;; TODO. The quo component for data item doesn't support showing accounts yet - :status :default - :size :small - :title (i18n/label :t/account-title) - :subtitle name}])) + [{:source (quo.resources/get-network :ethereum)} + {:source (quo.resources/get-network :optimism)} + {:source (quo.resources/get-network :arbitrum)}]) -(defn- networks-data-item +(defn- connection-category [] - [quo/data-item - {:container-style style/detail-item - :blur? false - :description :default - :icon-right? true - :card? true - :label :none - :status :default - :size :small - :title (i18n/label :t/networks) - ;; TODO. The quo component for data-item does not support showing networks yet - :subtitle "Networks will show up here"}]) + (let [{:keys [name emoji customization-color]} (first (rf/sub + [:wallet/accounts-without-watched-accounts])) + data-item-common-props {:blur? false + :description :default + :card? false + :label :preview + :status :default + :size :default} + account-data-item-props (assoc data-item-common-props + :right-content {:type :accounts + :size :size-32 + :data [{:emoji emoji + :customization-color + customization-color}]} + :on-press #(js/alert "Not yet implemented") + :title (i18n/label :t/account-title) + :subtitle name + :icon-right? true + :right-icon :i/chevron-right + :icon-color colors/neutral-10) + networks-data-item-props (assoc data-item-common-props + :right-content {:type :network + :data + (get-placeholder-networks)} + :title (i18n/label :t/networks) + ;; TODO. The quo component for data-item + ;; does not support showing networks yet + :subtitle "Networks placeholder")] + [quo/category + {:blur? false + :list-type :data-item + :data [account-data-item-props + networks-data-item-props]}])) (defn- footer [] @@ -114,6 +121,5 @@ :footer [footer]} [rn/view [dapp-metadata] - [accounts-data-item] - [networks-data-item] + [connection-category] [approval-note]]]) From fd3a21a3200ea117e0f42982f91e9a6b2ed80df7 Mon Sep 17 00:00:00 2001 From: Jamie Caprani Date: Tue, 25 Jun 2024 16:56:11 +0200 Subject: [PATCH 02/10] fix(wallet): native share should point to opensea link (#20222) --- .../contexts/wallet/account/tabs/view.cljs | 5 +-- .../contexts/wallet/collectible/events.cljs | 33 ++++++++++++------- .../wallet/collectible/options/view.cljs | 23 +++++++++---- .../contexts/wallet/collectible/view.cljs | 12 ++++--- .../contexts/wallet/home/tabs/view.cljs | 17 ++++------ 5 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/status_im/contexts/wallet/account/tabs/view.cljs b/src/status_im/contexts/wallet/account/tabs/view.cljs index aabef2c98a..9a9a2179b3 100644 --- a/src/status_im/contexts/wallet/account/tabs/view.cljs +++ b/src/status_im/contexts/wallet/account/tabs/view.cljs @@ -16,12 +16,13 @@ (rf/dispatch [:wallet/get-collectible-details id])) (defn- on-collectible-long-press - [{:keys [preview-url collectible-details]}] + [{:keys [preview-url collectible-details id]}] (rf/dispatch [:show-bottom-sheet {:content (fn [] [options-drawer/view {:name (:name collectible-details) - :image (:uri preview-url)}])}])) + :image (:uri preview-url) + :id id}])}])) (defn- on-end-reached [] diff --git a/src/status_im/contexts/wallet/collectible/events.cljs b/src/status_im/contexts/wallet/collectible/events.cljs index 2c5a898fc4..96e31d99f3 100644 --- a/src/status_im/contexts/wallet/collectible/events.cljs +++ b/src/status_im/contexts/wallet/collectible/events.cljs @@ -1,5 +1,6 @@ (ns status-im.contexts.wallet.collectible.events (:require [camel-snake-kebab.extras :as cske] + [react-native.platform :as platform] [status-im.contexts.wallet.collectible.utils :as collectible-utils] [taoensso.timbre :as log] [utils.ethereum.chain :as chain] @@ -200,25 +201,35 @@ (rf/reg-event-fx :wallet/trigger-share-collectible (fn [_ [{:keys [title uri]}]] - {:fx [[:effects.share/open - {:title title - :message title - :url uri}]]})) + {:fx [[:dispatch + [:open-share + {:options (if platform/ios? + {:activityItemSources + [{:placeholderItem {:type :text + :content uri} + :item {:default {:type :url + :content uri}} + :linkMetadata {:title title}}]} + {:title title + :subject title + :url uri + :isNewTask true})}]]]})) (rf/reg-event-fx :wallet/share-collectible - (fn [_ [{:keys [title uri in-sheet?]}]] - (if in-sheet? + (fn [{:keys [db]} [{:keys [title token-id contract-address chain-id]}]] + (let [uri (collectible-utils/get-opensea-collectible-url + {:chain-id chain-id + :token-id token-id + :contract-address contract-address + :test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?]) + :is-goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])})] {:fx [[:dispatch [:hide-bottom-sheet]] [:dispatch-later {:ms 600 :dispatch [:wallet/trigger-share-collectible {:title title - :uri uri}]}]]} - {:fx [[:dispatch - [:wallet/trigger-share-collectible - {:title title - :uri uri}]]]}))) + :uri uri}]}]]}))) (rf/reg-event-fx :wallet/navigate-to-opensea diff --git a/src/status_im/contexts/wallet/collectible/options/view.cljs b/src/status_im/contexts/wallet/collectible/options/view.cljs index 094d5a5e38..cc0adc95bd 100644 --- a/src/status_im/contexts/wallet/collectible/options/view.cljs +++ b/src/status_im/contexts/wallet/collectible/options/view.cljs @@ -7,15 +7,18 @@ [utils.url :as url])) (defn view - [{:keys [image name chain-id address]}] - (let [uri (url/replace-port image (rf/sub [:mediaserver/port]))] + [{:keys [image name id]}] + (let [chain-id (get-in id [:contract-id :chain-id]) + token-id (:token-id id) + contract-address (get-in id [:contract-id :address]) + uri (url/replace-port image (rf/sub [:mediaserver/port]))] [quo/action-drawer [[{:icon :i/link :accessibility-label :view-on-etherscan :on-press (fn [] (rf/dispatch [:wallet/navigate-to-chain-explorer-from-bottom-sheet (external-links/get-explorer-url-by-chain-id chain-id) - address])) + contract-address])) :label (i18n/label :t/view-on-eth) :right-icon :i/external}] [{:icon :i/save @@ -34,6 +37,14 @@ :accessibility-label :share-collectible :label (i18n/label :t/share-collectible) :on-press #(rf/dispatch [:wallet/share-collectible - {:in-sheet? true - :title name - :uri uri}])}]]])) + {:token-id token-id + :contract-address contract-address + :chain-id chain-id + :title name}])}]]])) + +"222" +"https://nft-cdn.alchemy.com/eth-mainnet/219530f9b3a7901f02169334d593823e" +"Tengria #913" +{:contract-id {:chain-id 1 :address "0x1a4ceef5d575c2228d142ef862a9b60be8161e7f"} :token-id "913"} + +{:contract-id {:chain-id 1 :address "0x1a4ceef5d575c2228d142ef862a9b60be8161e7f"} :token-id "913"} diff --git a/src/status_im/contexts/wallet/collectible/view.cljs b/src/status_im/contexts/wallet/collectible/view.cljs index 7f3122f195..7b456d1c43 100644 --- a/src/status_im/contexts/wallet/collectible/view.cljs +++ b/src/status_im/contexts/wallet/collectible/view.cljs @@ -79,7 +79,8 @@ (js/setTimeout #(rf/dispatch [:wallet/clear-last-collectible-details]) 700)) (defn animated-header - [{:keys [scroll-amount title-opacity page-nav-type picture title description theme]}] + [{:keys [scroll-amount title-opacity page-nav-type picture title description theme + id]}] (let [blur-amount (header-animations/use-blur-amount scroll-amount) layer-opacity (header-animations/use-layer-opacity scroll-amount @@ -110,7 +111,8 @@ {:content (fn [] [options-drawer/view {:name title - :image picture}]) + :image picture + :id id}]) :theme theme}])}] :center-opacity title-opacity}]]]])) @@ -197,7 +199,8 @@ [options-drawer/view {:name collectible-name :image - preview-uri}])}])}]))) + preview-uri + :id id}])}])}]))) :on-collectible-load (fn [] ;; We need to delay the measurement because the ;; navigation has an animation @@ -246,7 +249,8 @@ {collection-name :name} collection-data] [rn/view {:style (style/background-color theme)} [animated-header - {:scroll-amount scroll-amount + {:id (:id collectible) + :scroll-amount scroll-amount :title-opacity title-opacity :page-nav-type :title-description :picture preview-uri diff --git a/src/status_im/contexts/wallet/home/tabs/view.cljs b/src/status_im/contexts/wallet/home/tabs/view.cljs index 1871381ea9..7ef4dcffe6 100644 --- a/src/status_im/contexts/wallet/home/tabs/view.cljs +++ b/src/status_im/contexts/wallet/home/tabs/view.cljs @@ -9,16 +9,13 @@ [utils.re-frame :as rf])) (defn- on-collectible-long-press - [{:keys [preview-url collectible-details id]}] - (let [chain-id (get-in id [:contract-id :chain-id]) - address (get-in id [:contract-id :address])] - (rf/dispatch [:show-bottom-sheet - {:content (fn [] - [options-drawer/view - {:chain-id chain-id - :address address - :name (:name collectible-details) - :image (:uri preview-url)}])}]))) + [{:keys [preview-url :collectible-data id]}] + (rf/dispatch [:show-bottom-sheet + {:content (fn [] + [options-drawer/view + {:id id + :name (:name collectible-data) + :image (:uri preview-url)}])}])) (defn- on-collectible-press [{:keys [id]}] From a92b50afea2684ed7046b20187dc4ef141c1a342 Mon Sep 17 00:00:00 2001 From: Tetiana Churikova Date: Tue, 25 Jun 2024 17:35:08 +0200 Subject: [PATCH 03/10] .github: add default prio label for bug (#20557) --- .github/ISSUE_TEMPLATE/bug-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 13a10bb2fd..22ff0e1874 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -2,7 +2,7 @@ name: MVPBug Report about: MVPBug Report title: '' -labels: 'E:Mobile Bug MVP' +labels: ['E:Mobile Bug MVP', ':1234: low prio'] assignees: '' --- From 136c3c0032da96a2c9d33309df040fcc1f4c3710 Mon Sep 17 00:00:00 2001 From: Yevheniia Berdnyk Date: Tue, 25 Jun 2024 19:06:19 +0300 Subject: [PATCH 04/10] e2e: fixed KeyError for missed SauceLabs session id --- test/appium/support/github_report.py | 9 ++++++--- test/appium/support/testrail_report.py | 19 ++++++++++++++----- .../old_ui/medium/test_browser_profile.py | 6 +++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/test/appium/support/github_report.py b/test/appium/support/github_report.py index 50e5cb69cf..9a1a37a868 100644 --- a/test/appium/support/github_report.py +++ b/test/appium/support/github_report.py @@ -160,10 +160,13 @@ class GithubHtmlReport(BaseTestReport): html += "Device %d:" % i html += "
    " if test_run.first_commands: - html += "
  • Steps, video, logs
  • " % \ - self.get_sauce_job_url(job_id, test_run.first_commands[job_id]) + try: + first_command = test_run.first_commands[job_id] + except KeyError: + first_command = 0 else: - html += "
  • Steps, video, logs
  • " % self.get_sauce_job_url(job_id) + first_command = 0 + html += "
  • Steps, video, logs
  • " % self.get_sauce_job_url(job_id, first_command) # if test_run.error: # html += "
  • Failure screenshot
  • " % self.get_sauce_final_screenshot_url(job_id) html += "

" diff --git a/test/appium/support/testrail_report.py b/test/appium/support/testrail_report.py index e6ad5de354..63e6114c22 100644 --- a/test/appium/support/testrail_report.py +++ b/test/appium/support/testrail_report.py @@ -190,7 +190,10 @@ class TestrailReport(BaseTestReport): test_steps += step + "\n" for i, device in enumerate(last_testrun.jobs): if last_testrun.first_commands: - first_command = last_testrun.first_commands[device] + try: + first_command = last_testrun.first_commands[device] + except KeyError: + first_command = 0 else: first_command = 0 try: @@ -233,7 +236,10 @@ class TestrailReport(BaseTestReport): continue for res in results: if last_testrun.first_commands: - pattern = r"%s\?auth=.*#%s" % (device, str(last_testrun.first_commands[device])) + try: + pattern = r"%s\?auth=.*#%s" % (device, str(last_testrun.first_commands[device])) + except KeyError: + pattern = device else: pattern = device if re.findall(pattern, res['comment']): @@ -285,10 +291,13 @@ class TestrailReport(BaseTestReport): error = "```%s```\n **%s** \n" % (code_error, no_code_error_str) for job_id, f in last_testrun.jobs.items(): if last_testrun.first_commands: - job_url = self.get_sauce_job_url(job_id=job_id, - first_command=last_testrun.first_commands[job_id]) + try: + first_command = last_testrun.first_commands[job_id] + except KeyError: + first_command = 0 else: - job_url = self.get_sauce_job_url(job_id=job_id) + first_command = 0 + job_url = self.get_sauce_job_url(job_id=job_id, first_command=first_command) case_info = "Logs for device %d: [steps](%s), [failure screenshot](%s)" \ % (f, job_url, self.get_sauce_final_screenshot_url(job_id)) diff --git a/test/appium/tests/old_ui/medium/test_browser_profile.py b/test/appium/tests/old_ui/medium/test_browser_profile.py index 685876545b..c0416c1d7e 100644 --- a/test/appium/tests/old_ui/medium/test_browser_profile.py +++ b/test/appium/tests/old_ui/medium/test_browser_profile.py @@ -2,7 +2,7 @@ import time import pytest -from tests import marks, common_password, used_fleet +from tests import marks, common_password from tests.base_test_case import create_shared_drivers, MultipleSharedDeviceTestCase from views.sign_in_view import SignInView from tests.users import basic_user, ens_user, ens_user_message_sender, transaction_senders, chat_users @@ -415,8 +415,8 @@ class TestBrowserProfileOneDevice(MultipleSharedDeviceTestCase): profile = self.home.profile_button.click() profile.advanced_button.click() - if not profile.element_by_text(used_fleet).is_element_displayed(): - self.errors.append('%s is not selected by default' % used_fleet) + # if not profile.element_by_text(used_fleet).is_element_displayed(): + # self.errors.append('%s is not selected by default' % used_fleet) self.home.just_fyi('Set another fleet and check that changes are applied') profile.fleet_setting_button.click() From 6931fd005267e0b52efcba5650bc3ab39dd2522b Mon Sep 17 00:00:00 2001 From: Jamie Caprani Date: Wed, 26 Jun 2024 11:05:19 +0200 Subject: [PATCH 05/10] chore(wallet/shell): minor fixes from design review (#20494) * chore(wallet): make recent tab fullscreen for empty view * chore(wallet): hide advanced button on send page * chore(wallet): hide estimated fees when no routes found * chore(wallet): update emoji icon to edit * chore(wallet): update key pair placeholder to use keypair example * chore(shell): feature flag saved address option in scanner --- .../common/floating_button_page/view.cljs | 6 +++-- .../sheets/scanned_wallet_address.cljs | 10 ++++---- .../add_account/create_account/view.cljs | 2 +- .../create_or_edit_account/view.cljs | 2 +- .../wallet/send/input_amount/view.cljs | 24 ++++++++++--------- .../wallet/send/select_address/tabs/view.cljs | 12 ++++++---- .../wallet/send/select_address/view.cljs | 9 +++---- src/status_im/feature_flags.cljs | 2 ++ translations/en.json | 2 +- 9 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/status_im/common/floating_button_page/view.cljs b/src/status_im/common/floating_button_page/view.cljs index 31b8f59bcd..f67b5f98a2 100644 --- a/src/status_im/common/floating_button_page/view.cljs +++ b/src/status_im/common/floating_button_page/view.cljs @@ -58,7 +58,7 @@ (defn view [{:keys [header footer customization-color footer-container-padding header-container-style - gradient-cover? keyboard-should-persist-taps] + content-container-style gradient-cover? keyboard-should-persist-taps] :or {footer-container-padding (safe-area/get-top)}} & children] (reagent/with-let [scroll-view-ref (atom nil) @@ -110,7 +110,9 @@ :always-bounce-vertical @keyboard-did-show? :shows-vertical-scroll-indicator false :keyboard-should-persist-taps keyboard-should-persist-taps} - (into [rn/view {:on-layout set-content-container-height}] + (into [rn/view + {:style content-container-style + :on-layout set-content-container-height}] children)] [rn/keyboard-avoiding-view {:style style/keyboard-avoiding-view diff --git a/src/status_im/contexts/shell/qr_reader/sheets/scanned_wallet_address.cljs b/src/status_im/contexts/shell/qr_reader/sheets/scanned_wallet_address.cljs index 731848a58a..f5d1bf8964 100644 --- a/src/status_im/contexts/shell/qr_reader/sheets/scanned_wallet_address.cljs +++ b/src/status_im/contexts/shell/qr_reader/sheets/scanned_wallet_address.cljs @@ -1,6 +1,7 @@ (ns status-im.contexts.shell.qr-reader.sheets.scanned-wallet-address (:require [quo.core :as quo] + [status-im.feature-flags :as ff] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -20,7 +21,8 @@ :recipient address :stack-id :wallet-select-address :start-flow? true}]))} - {:icon :i/save - :accessibility-label :save-address - :label (i18n/label :t/save-address) - :on-press #(js/alert "feature not implemented")}]]]]) + (when (ff/enabled? :ff/wallet.saved-addresses) + {:icon :i/save + :accessibility-label :save-address + :label (i18n/label :t/save-address) + :on-press #(js/alert "feature not implemented")})]]]]) diff --git a/src/status_im/contexts/wallet/add_account/create_account/view.cljs b/src/status_im/contexts/wallet/add_account/create_account/view.cljs index e5d5c9dbae..9693f192f9 100644 --- a/src/status_im/contexts/wallet/add_account/create_account/view.cljs +++ b/src/status_im/contexts/wallet/add_account/create_account/view.cljs @@ -70,7 +70,7 @@ :icon-only? true :on-press #(rf/dispatch [:emoji-picker/open {:on-select on-select-emoji}]) :container-style style/reaction-button-container} - :i/reaction]]) + :i/edit]]) (defn- input [_] diff --git a/src/status_im/contexts/wallet/common/screen_base/create_or_edit_account/view.cljs b/src/status_im/contexts/wallet/common/screen_base/create_or_edit_account/view.cljs index 7571412f0b..d617661dce 100644 --- a/src/status_im/contexts/wallet/common/screen_base/create_or_edit_account/view.cljs +++ b/src/status_im/contexts/wallet/common/screen_base/create_or_edit_account/view.cljs @@ -49,7 +49,7 @@ :icon-only? true :on-press #(rf/dispatch [:emoji-picker/open {:on-select on-change-emoji}]) :container-style style/reaction-button-container} - :i/reaction]] + :i/edit]] [rn/view [quo/title-input diff --git a/src/status_im/contexts/wallet/send/input_amount/view.cljs b/src/status_im/contexts/wallet/send/input_amount/view.cljs index 73b10427a4..d2af04b98e 100644 --- a/src/status_im/contexts/wallet/send/input_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/view.cljs @@ -15,6 +15,7 @@ [status-im.contexts.wallet.send.routes.view :as routes] [status-im.contexts.wallet.sheets.buy-token.view :as buy-token] [status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert] + [status-im.feature-flags :as ff] [utils.debounce :as debounce] [utils.i18n :as i18n] [utils.money :as money] @@ -24,16 +25,17 @@ (defn- estimated-fees [{:keys [loading-routes? fees amount]}] [rn/view {:style style/estimated-fees-container} - [rn/view {:style style/estimated-fees-content-container} - [quo/button - {:icon-only? true - :type :outline - :size 32 - :inner-style {:opacity 1} - :accessibility-label :advanced-button - :disabled? loading-routes? - :on-press #(js/alert "Not implemented yet")} - :i/advanced]] + (when (ff/enabled? ::ff/wallet.advanced-sending) + [rn/view {:style style/estimated-fees-content-container} + [quo/button + {:icon-only? true + :type :outline + :size 32 + :inner-style {:opacity 1} + :accessibility-label :advanced-button + :disabled? loading-routes? + :on-press #(js/alert "Not implemented yet")} + :i/advanced]]) [quo/data-item {:container-style style/fees-data-item :status (if loading-routes? :loading :default) @@ -376,7 +378,7 @@ sender-network-values token-not-supported-in-receiver-networks?) [token-not-available token-symbol receiver-networks token-networks]) - (when (or loading-routes? route) + (when (and (not no-routes-found?) (or loading-routes? route)) [estimated-fees {:loading-routes? loading-routes? :fees fee-formatted diff --git a/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs b/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs index 5137e7ac77..43b042e167 100644 --- a/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs +++ b/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs @@ -82,11 +82,12 @@ empty-state-component (rn/use-memo (fn [] [quo/empty-state - {:title (i18n/label :t/no-saved-addresses) - :description (i18n/label - :t/you-like-to-type-43-characters) - :image (resources/get-themed-image :sweating-man - theme)}]) + {:title (i18n/label :t/no-saved-addresses) + :description (i18n/label + :t/you-like-to-type-43-characters) + :container-style style/empty-container-style + :image (resources/get-themed-image :sweating-man + theme)}]) [theme])] [rn/section-list {:key-fn :title @@ -94,6 +95,7 @@ :render-section-header-fn section-header :sections group-saved-addresses :render-fn saved-address + :content-container-style {:flex 1} :empty-component empty-state-component}])) (defn view diff --git a/src/status_im/contexts/wallet/send/select_address/view.cljs b/src/status_im/contexts/wallet/send/select_address/view.cljs index e887504dbb..c1dc144f09 100644 --- a/src/status_im/contexts/wallet/send/select_address/view.cljs +++ b/src/status_im/contexts/wallet/send/select_address/view.cljs @@ -136,7 +136,7 @@ :keyboard-should-persist-taps :handled :render-fn suggestion-component}]])) -(defn- f-view +(defn view [] (let [on-close (fn [] (rf/dispatch [:wallet/clean-scanned-address]) @@ -155,7 +155,8 @@ local-suggestion-address (rf/sub [:wallet/local-suggestions->full-address]) color (rf/sub [:wallet/current-viewing-account-color])] [floating-button-page/view - {:footer-container-padding 0 + {:content-container-style {:flex 1} + :footer-container-padding 0 :keyboard-should-persist-taps true :header [account-switcher/view {:on-press on-close @@ -205,7 +206,3 @@ :scrollable? true :on-change on-change-tab}] [tabs/view {:selected-tab selected-tab}]])])))) - -(defn view - [] - [:f> f-view]) diff --git a/src/status_im/feature_flags.cljs b/src/status_im/feature_flags.cljs index 4cd2346987..48670c02bb 100644 --- a/src/status_im/feature_flags.cljs +++ b/src/status_im/feature_flags.cljs @@ -16,6 +16,7 @@ ::settings.saved-addresses (enabled-in-env? :FLAG_WALLET_SETTINGS_SAVED_ADDRESSES_ENABLED) ::shell.jump-to (enabled-in-env? :ENABLE_JUMP_TO) + ::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING) ::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE) ::wallet.assets-modal-manage-tokens (enabled-in-env? :FLAG_ASSETS_MODAL_MANAGE_TOKENS) ::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED) @@ -24,6 +25,7 @@ ::wallet.graph (enabled-in-env? :FLAG_GRAPH_ENABLED) ::wallet.import-private-key (enabled-in-env? :FLAG_IMPORT_PRIVATE_KEY_ENABLED) ::wallet.long-press-watch-only-asset (enabled-in-env? :FLAG_LONG_PRESS_WATCH_ONLY_ASSET_ENABLED) + ::wallet.saved-addresses (enabled-in-env? :WALLET_SAVED_ADDRESSES) ::wallet.swap (enabled-in-env? :FLAG_SWAP_ENABLED) ::wallet.wallet-connect (enabled-in-env? :FLAG_WALLET_CONNECT_ENABLED)}) diff --git a/translations/en.json b/translations/en.json index 27b727e98b..f6bb549e2d 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2612,7 +2612,7 @@ "generating-keypair": "Generating key pair...", "keypair-name": "Key pair name", "keypair-name-description": "Name key pair for your own personal reference", - "keypair-name-input-placeholder": "Collectibles account, Old vault....", + "keypair-name-input-placeholder": "Collectibles key pair, Old vault....", "key-pair-name-updated": "Key pair name updated", "key-pair-removed": "Key pair and derived accounts has been removed", "goerli-testnet-toggle-confirmation": "Are you sure you want to toggle Goerli? This will log you out and you will have to login again.", From 256f3f8f24ab02ebf99b1813871abf2466b881de Mon Sep 17 00:00:00 2001 From: Sean Hagstrom Date: Wed, 26 Jun 2024 13:16:00 +0100 Subject: [PATCH 06/10] feat!: add key pairs and accounts settings to wallet settings (#20464) * tweak: use support blur colors for action drawer icons * tweak: support blur colors for drawer-top icon * tweak: support blur colors for account list inside keypair component * tweak: use blur colors for missing-keypair bottom sheet actions * feat: remove feature-flag for key-pairs and accounts inside wallet settings * fix: ensure key-pairs-and-accounts settings are visible * tweak: display key-pair rename screen as full-screen modal * tweak: animate key-pair scanning screen as modal * fix: do not allow user to rename key-pair to an existing key-pair name * fix: ensure we visualise the validation error for key-pair name that is too long * fix: ensure we can see the recovery-phrase suggestions when testnet-mode is active * tweak: show recovery-phrase errors when keyboard is hidden * fix: ensure we do not re-hash password * fix: ensure we call `on-close` function when successfully handling biometrics auth * fix: ensure we clear error states when editing the recovery-phrase input * fix: use blur styles for standard authentication password input * chore: add labels for qr validation * tweak: handle display import-qr error and allow for re-scanning * tweak: update blur background for all bottom-sheets * chore: add feature-flag for import-all key-pairs button for missing key-pairs * tidy: remove unused variable * fix: ensure layout for android is correct when entering seed-phrase in testnet-mode * fix: ensure we return the updated db when updating the db with backup key-pair * tweak: coerce nil to empty string * tweak: change validation error message for short key-pair name * tweak: hide the options icon for the default key-pair inside key-pairs and accounts settings --- .../drawers/action_drawers/view.cljs | 13 ++- .../components/drawers/drawer_top/view.cljs | 4 +- .../list_items/account_list_card/view.cljs | 3 +- src/quo/components/wallet/keypair/view.cljs | 13 ++- .../wallet/missing_keypairs/view.cljs | 15 +-- src/status_im/common/bottom_sheet/style.cljs | 10 +- src/status_im/common/bottom_sheet/view.cljs | 4 +- .../common/enter_seed_phrase/style.cljs | 16 ++- .../common/enter_seed_phrase/view.cljs | 21 ++-- src/status_im/common/scan_qr_code/view.cljs | 6 +- .../enter_password/view.cljs | 1 + .../standard_authentication/events.cljs | 7 +- src/status_im/common/validation/keypair.cljs | 8 +- .../common/validation/keypair_test.cljs | 7 +- .../contexts/settings/wallet/events.cljs | 24 ++-- .../keypairs_and_accounts/actions/view.cljs | 18 ++- .../missing_keypairs/scan_qr/view.cljs | 9 +- .../keypairs_and_accounts/rename/style.cljs | 3 +- .../keypairs_and_accounts/rename/view.cljs | 110 ++++++++++-------- .../wallet/keypairs_and_accounts/view.cljs | 37 +++--- .../wallet/network_settings/view.cljs | 12 +- .../sheets/address_options/view.cljs | 10 +- .../settings/wallet/wallet_options/view.cljs | 13 +-- src/status_im/contexts/wallet/effects.cljs | 2 +- src/status_im/contexts/wallet/events.cljs | 23 ++-- src/status_im/feature_flags.cljs | 4 +- src/status_im/navigation/screens.cljs | 4 +- src/status_im/subs/wallet/wallet.cljs | 8 +- src/status_im/subs/wallet/wallet_test.cljs | 14 ++- translations/en.json | 3 + 30 files changed, 245 insertions(+), 177 deletions(-) diff --git a/src/quo/components/drawers/action_drawers/view.cljs b/src/quo/components/drawers/action_drawers/view.cljs index 22786fdb59..0290e8423e 100644 --- a/src/quo/components/drawers/action_drawers/view.cljs +++ b/src/quo/components/drawers/action_drawers/view.cljs @@ -8,10 +8,11 @@ [react-native.core :as rn])) (defn- get-icon-color - [danger? theme] - (if danger? - (colors/theme-colors colors/danger-50 colors/danger-60 theme) - (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))) + [blur? danger? theme] + (cond + danger? (colors/theme-colors colors/danger-50 colors/danger-60 theme) + blur? colors/white-opa-70 + :else (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))) (defn- divider [theme blur?] @@ -51,7 +52,7 @@ :accessible true :style (style/left-icon sub-label)} [icon/icon icon - {:color (or icon-color (get-icon-color danger? theme)) + {:color (or icon-color (get-icon-color blur? danger? theme)) :no-color no-icon-color? :size 20}]]) [rn/view @@ -84,7 +85,7 @@ :accessible true :accessibility-label :right-icon-for-action} [icon/icon right-icon - {:color (get-icon-color danger? theme) + {:color (get-icon-color blur? danger? theme) :size 20}]]) (when (= state :selected) [rn/view {:style style/right-icon} diff --git a/src/quo/components/drawers/drawer_top/view.cljs b/src/quo/components/drawers/drawer_top/view.cljs index 4221be2049..5c5aa98a64 100644 --- a/src/quo/components/drawers/drawer_top/view.cljs +++ b/src/quo/components/drawers/drawer_top/view.cljs @@ -18,7 +18,7 @@ (defn- left-image [{:keys [type customization-color account-avatar-emoji account-avatar-type icon-avatar - profile-picture]}] + profile-picture blur?]}] (case type :account [account-avatar/view {:customization-color customization-color @@ -28,6 +28,7 @@ :keypair [icon-avatar/icon-avatar {:icon icon-avatar :border? true + :blur? blur? :color :neutral}] :default-keypair [user-avatar/user-avatar @@ -213,6 +214,7 @@ [rn/view {:style style/left-container} [left-image {:type type + :blur? blur? :customization-color customization-color :account-avatar-emoji account-avatar-emoji :account-avatar-type account-avatar-type diff --git a/src/quo/components/list_items/account_list_card/view.cljs b/src/quo/components/list_items/account_list_card/view.cljs index e1e6bc8e96..1ac4ca0f8c 100644 --- a/src/quo/components/list_items/account_list_card/view.cljs +++ b/src/quo/components/list_items/account_list_card/view.cljs @@ -31,7 +31,8 @@ :size :paragraph-2} (:name account-props)] [address-text/view - {:networks networks + {:blur? blur? + :networks networks :address (:address account-props) :format :short}]]] (when (= action :icon) diff --git a/src/quo/components/wallet/keypair/view.cljs b/src/quo/components/wallet/keypair/view.cljs index a31e0b3178..d6ab053cf1 100644 --- a/src/quo/components/wallet/keypair/view.cljs +++ b/src/quo/components/wallet/keypair/view.cljs @@ -47,12 +47,13 @@ :accessibility-label :title} [text/text {:weight :semi-bold} (if (= type :default-keypair) (keypair-string full-name) full-name)] - (if (= action :selector) - [selectors/view - {:type :radio - :checked? selected? - :blur? blur? - :customization-color customization-color}] + (case action + :none nil + :selector [selectors/view + {:type :radio + :checked? selected? + :blur? blur? + :customization-color customization-color}] [rn/pressable {:on-press on-options-press} [icon/icon :i/options {:color (if blur? diff --git a/src/quo/components/wallet/missing_keypairs/view.cljs b/src/quo/components/wallet/missing_keypairs/view.cljs index 0e465fdd34..c2fe6ca60f 100644 --- a/src/quo/components/wallet/missing_keypairs/view.cljs +++ b/src/quo/components/wallet/missing_keypairs/view.cljs @@ -11,7 +11,7 @@ [utils.i18n :as i18n])) (defn title-view - [{:keys [keypairs blur? on-import-press]}] + [{:keys [keypairs blur? on-import-press show-import-all?]}] (let [theme (quo.theme/use-theme)] [rn/view {:accessibility-label :title @@ -29,12 +29,13 @@ :style {:color colors/warning-60}} (i18n/label :t/amount-missing-keypairs {:amount (str (count keypairs))})] - [button/button - {:type :outline - :background :blur - :size 24 - :on-press on-import-press} - (i18n/label :t/import)]] + (when show-import-all? + [button/button + {:type :outline + :background :blur + :size 24 + :on-press on-import-press} + (i18n/label :t/import)])] [text/text {:size :paragraph-2 :style (style/subtitle blur? theme)} diff --git a/src/status_im/common/bottom_sheet/style.cljs b/src/status_im/common/bottom_sheet/style.cljs index 5c7e474575..ca83a1fb04 100644 --- a/src/status_im/common/bottom_sheet/style.cljs +++ b/src/status_im/common/bottom_sheet/style.cljs @@ -1,7 +1,6 @@ (ns status-im.common.bottom-sheet.style (:require - [quo.foundations.colors :as colors] - [react-native.platform :as platform])) + [quo.foundations.colors :as colors])) (def ^:private sheet-border-radius 20) @@ -22,11 +21,8 @@ :left 0 :right 0}) -(defn shell-bg - [blur-background] - {:background-color (if blur-background - blur-background - (if platform/ios? colors/white-opa-5 colors/neutral-100-opa-90)) +(def shell-bg + {:background-color colors/bottom-sheet-background-blur :flex 1}) (def shell-bg-container diff --git a/src/status_im/common/bottom_sheet/view.cljs b/src/status_im/common/bottom_sheet/view.cljs index 98fec0f694..a941d9bad0 100644 --- a/src/status_im/common/bottom_sheet/view.cljs +++ b/src/status_im/common/bottom_sheet/view.cljs @@ -63,7 +63,7 @@ (defn view [{:keys [hide? insets]} {:keys [content selected-item padding-bottom-override border-radius on-close shell? - gradient-cover? customization-color hide-handle? blur-radius blur-background] + gradient-cover? customization-color hide-handle? blur-radius] :or {border-radius 12}}] (let [theme (quo.theme/use-theme) {window-height :height} (rn/get-window) @@ -134,7 +134,7 @@ (when shell? [rn/view {:style style/shell-bg-container} [quo/blur - {:style (style/shell-bg blur-background) + {:style style/shell-bg :blur-radius (or blur-radius 20) :blur-amount 32 :blur-type :transparent diff --git a/src/status_im/common/enter_seed_phrase/style.cljs b/src/status_im/common/enter_seed_phrase/style.cljs index 1fb6a9b471..567e7bbd22 100644 --- a/src/status_im/common/enter_seed_phrase/style.cljs +++ b/src/status_im/common/enter_seed_phrase/style.cljs @@ -1,6 +1,5 @@ (ns status-im.common.enter-seed-phrase.style - (:require - [react-native.safe-area :as safe-area])) + (:require [react-native.platform :as platform])) (def full-layout {:flex 1}) @@ -11,6 +10,13 @@ :left 0 :right 0}) +(defn recovery-phrase-container + [{:keys [banner-offset insets keyboard-shown?]}] + {:flex 1 + :padding-bottom (if keyboard-shown? + (when platform/ios? banner-offset) + (:bottom insets))}) + (def form-container {:flex 1 :padding-horizontal 20 @@ -29,9 +35,7 @@ :margin-top 12 :margin-horizontal -20}) -(defn continue-button - [keyboard-shown?] - {:margin-top :auto - :margin-bottom (when-not keyboard-shown? (safe-area/get-bottom))}) +(def continue-button + {:margin-top :auto}) (def keyboard-container {:margin-top :auto}) diff --git a/src/status_im/common/enter_seed_phrase/view.cljs b/src/status_im/common/enter_seed_phrase/view.cljs index 361ec2e619..16ae317a94 100644 --- a/src/status_im/common/enter_seed_phrase/view.cljs +++ b/src/status_im/common/enter_seed_phrase/view.cljs @@ -96,7 +96,7 @@ (take 7))) (defn recovery-phrase-screen - [{:keys [keypair title recovering-keypair? render-controls]}] + [{:keys [banner-offset initial-insets keypair title recovering-keypair? render-controls]}] (reagent/with-let [keyboard-shown? (reagent/atom false) keyboard-show-listener (.addListener rn/keyboard "keyboardDidShow" @@ -114,7 +114,8 @@ seed-phrase (reagent/atom "") on-change-seed-phrase (fn [new-phrase] (when @invalid-seed-phrase? - (reset! invalid-seed-phrase? false) + (reset! invalid-seed-phrase? false)) + (when @incorrect-seed-phrase? (reset! incorrect-seed-phrase? false)) (reset! seed-phrase new-phrase)) on-submit (fn [] @@ -161,7 +162,10 @@ button-disabled? (or error-state? (not (constants/seed-phrase-valid-length word-count)) (not all-words-valid?))] - [:<> + [rn/view + {:style (style/recovery-phrase-container {:insets initial-insets + :banner-offset banner-offset + :keyboard-shown? @keyboard-shown?})} [recovery-phrase-form {:title title :keypair keypair @@ -172,18 +176,18 @@ (if (fn? render-controls) (render-controls {:submit-disabled? button-disabled? :keyboard-shown? @keyboard-shown? - :container-style (style/continue-button @keyboard-shown?) + :container-style style/continue-button :prepare-seed-phrase secure-clean-seed-phrase :focus-input focus-input :seed-phrase (security/mask-data @seed-phrase) :set-incorrect-seed-phrase set-incorrect-seed-phrase}) [quo/button - {:container-style (style/continue-button @keyboard-shown?) + {:container-style style/continue-button :type :primary :disabled? button-disabled? :on-press on-submit} (i18n/label :t/continue)])] - (when @keyboard-shown? + (when (or @keyboard-shown? error-state?) [rn/view {:style style/keyboard-container} [quo/predictive-keyboard {:type suggestions-state @@ -197,7 +201,8 @@ (defn screen [{:keys [initial-insets title keypair navigation-icon recovering-keypair? render-controls]}] - (let [{navigation-bar-top :top} initial-insets] + (let [{navigation-bar-top :top} initial-insets + banner-offset (rf/sub [:alert-banners/top-margin])] [rn/view {:style style/full-layout} [rn/keyboard-avoiding-view {:style style/page-container} [quo/page-nav @@ -210,6 +215,8 @@ {:title title :keypair keypair :render-controls render-controls + :banner-offset banner-offset + :initial-insets initial-insets :recovering-keypair? recovering-keypair?}]]])) (defn view diff --git a/src/status_im/common/scan_qr_code/view.cljs b/src/status_im/common/scan_qr_code/view.cljs index 8993454abf..8b2eb7e7b4 100644 --- a/src/status_im/common/scan_qr_code/view.cljs +++ b/src/status_im/common/scan_qr_code/view.cljs @@ -195,7 +195,7 @@ true) (defn view - [{:keys [title subtitle validate-fn on-success-scan error-message share-button?]}] + [{:keys [title subtitle validate-fn on-success-scan error-message share-button? import-keypair?]}] (let [insets (safe-area/get-insets) qr-code-succeed? (reagent/atom false) qr-view-finder (reagent/atom {}) @@ -233,7 +233,9 @@ :set-qr-code-succeeded (fn [value] (when on-success-scan (on-success-scan value)) - (rf/dispatch [:navigate-back])) + (if import-keypair? + (set-rescan-timeout) + (rf/dispatch [:navigate-back]))) :set-rescan-timeout set-rescan-timeout}]) [rn/view {:style (style/root-container (:top insets))} [header diff --git a/src/status_im/common/standard_authentication/enter_password/view.cljs b/src/status_im/common/standard_authentication/enter_password/view.cljs index d6d2b2c475..398bf78a9a 100644 --- a/src/status_im/common/standard_authentication/enter_password/view.cljs +++ b/src/status_im/common/standard_authentication/enter_password/view.cljs @@ -33,6 +33,7 @@ :size 24}]] [password-input/view {:on-press-biometrics on-press-biometrics + :blur? true :processing processing :error error :default-password password diff --git a/src/status_im/common/standard_authentication/events.cljs b/src/status_im/common/standard_authentication/events.cljs index 5a22fdc662..400eee1970 100644 --- a/src/status_im/common/standard_authentication/events.cljs +++ b/src/status_im/common/standard_authentication/events.cljs @@ -20,7 +20,7 @@ (rf/reg-event-fx :standard-auth/authorize authorize) (defn authorize-with-biometric - [_ [{:keys [on-auth-success on-auth-fail] :as args}]] + [_ [{:keys [on-auth-success on-auth-fail on-close] :as args}]] (let [args-with-biometric-btn (assoc args :on-press-biometric @@ -31,7 +31,10 @@ {:prompt-message (i18n/label :t/biometric-auth-confirm-message) :on-cancel #(rf/dispatch [:standard-auth/authorize-with-password args-with-biometric-btn]) - :on-success #(rf/dispatch [:standard-auth/on-biometric-success on-auth-success]) + :on-success (fn [] + (when (fn? on-close) + (on-close)) + (rf/dispatch [:standard-auth/on-biometric-success on-auth-success])) :on-fail (fn [err] (rf/dispatch [:standard-auth/authorize-with-password args-with-biometric-btn]) diff --git a/src/status_im/common/validation/keypair.cljs b/src/status_im/common/validation/keypair.cljs index 5a71749817..c7f4c0550a 100644 --- a/src/status_im/common/validation/keypair.cljs +++ b/src/status_im/common/validation/keypair.cljs @@ -14,10 +14,12 @@ (> (-> s str string/trim count) constants/key-pair-name-max-length)) (defn validation-keypair-name - [s] + [s existing-keypair-names] (cond (string/blank? s) nil (validators/has-emojis? s) (i18n/label :t/key-name-error-emoji) (validators/has-special-characters? s) (i18n/label :t/key-name-error-special-char) - (keypair-too-short? s) (i18n/label :t/your-key-pair-name-is-too-short) - (keypair-too-long? s) (i18n/label :t/your-key-pair-name-is-too-long))) + (keypair-too-short? s) (i18n/label :t/key-name-error-too-short + {:count constants/key-pair-name-min-length}) + (keypair-too-long? s) (i18n/label :t/your-key-pair-name-is-too-long) + (contains? existing-keypair-names s) (i18n/label :t/key-name-error-taken))) diff --git a/src/status_im/common/validation/keypair_test.cljs b/src/status_im/common/validation/keypair_test.cljs index 08d83c0a65..30a5faa8e1 100644 --- a/src/status_im/common/validation/keypair_test.cljs +++ b/src/status_im/common/validation/keypair_test.cljs @@ -2,6 +2,7 @@ (:require [cljs.test :refer-macros [deftest are]] [status-im.common.validation.keypair :as keypair-validator] + [status-im.constants :as constants] [utils.i18n :as i18n])) (deftest keypair-name-too-short-test @@ -18,10 +19,12 @@ (deftest validation-keypair-name-test (are [arg expected] - (= (keypair-validator/validation-keypair-name arg) expected) + (= (keypair-validator/validation-keypair-name arg #{"Collection"}) expected) nil nil "" nil "name !" (i18n/label :t/key-name-error-special-char) "Hello 😊" (i18n/label :t/key-name-error-emoji) - "abc" (i18n/label :t/your-key-pair-name-is-too-short) + "abc" (i18n/label :t/key-name-error-too-short + {:count constants/key-pair-name-min-length}) + "Collection" (i18n/label :t/key-name-error-taken) (apply str (repeat 25 "a")) (i18n/label :t/your-key-pair-name-is-too-long))) diff --git a/src/status_im/contexts/settings/wallet/events.cljs b/src/status_im/contexts/settings/wallet/events.cljs index 25cdb6c9de..2485fd4a08 100644 --- a/src/status_im/contexts/settings/wallet/events.cljs +++ b/src/status_im/contexts/settings/wallet/events.cljs @@ -92,23 +92,28 @@ (rf/reg-event-fx :wallet/make-keypairs-accounts-fully-operable make-keypairs-accounts-fully-operable) (defn connection-string-for-import-keypair - [{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string]}]] + [{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string on-success]}]] (let [key-uid (get-in db [:profile/profile :key-uid])] {:fx [[:effects.syncing/import-keypairs-keystores {:key-uid key-uid :sha3-pwd sha3-pwd :keypairs-key-uids keypairs-key-uids :connection-string connection-string - :on-success #(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable %]) - :on-fail #(rf/dispatch [:toasts/upsert - {:type :negative - :theme :dark - :text %}])}]]})) + :on-success (fn [key-uids] + (rf/call-continuation on-success) + (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/reg-event-fx :wallet/connection-string-for-import-keypair connection-string-for-import-keypair) (defn success-keypair-qr-scan - [_ [connection-string keypairs-key-uids]] + [_ [connection-string keypairs-key-uids on-import-success]] {:fx [[:dispatch [:standard-auth/authorize-with-password {:blur? true @@ -120,7 +125,8 @@ [:wallet/connection-string-for-import-keypair {:connection-string connection-string :keypairs-key-uids keypairs-key-uids - :sha3-pwd password}]))}]]]}) + :sha3-pwd password + :on-success on-import-success}]))}]]]}) (rf/reg-event-fx :wallet/success-keypair-qr-scan success-keypair-qr-scan) @@ -146,7 +152,7 @@ {:fx [[:json-rpc/call [{:method "accounts_makePrivateKeyKeypairFullyOperable" :params [(security/safe-unmask-data private-key) - (-> password security/safe-unmask-data native-module/sha3)] + (security/safe-unmask-data password)] :on-success on-success :on-error on-error}]]]}) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs index 622b64c272..6eed006d40 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs @@ -41,31 +41,37 @@ [quo/action-drawer [(when has-paired-device (if-not missing-keypair? - [{:icon :i/qr-code + [{:blur? true + :icon :i/qr-code :accessibility-label :show-key-pr-qr :label (i18n/label :t/show-encrypted-qr-of-key-pairs) :on-press on-show-qr}] - [{:icon :i/scan + [{:blur? true + :icon :i/scan :accessibility-label :import-by-scan-qr :label (i18n/label :t/import-by-scanning-encrypted-qr) :on-press on-scan-qr}])) (when (= (:type drawer-props) :keypair) [(when missing-keypair? (case (:type keypair) - :seed {:icon :i/seed + :seed {:blur? true + :icon :i/seed :accessibility-label :import-seed-phrase :label (i18n/label :t/import-by-entering-recovery-phrase) :on-press on-import-seed-phrase} - :key {:icon :i/key + :key {:blur? true + :icon :i/key :accessibility-label :import-private-key :label (i18n/label :t/import-by-entering-private-key) :on-press on-import-private-key} nil)) - {:icon :i/edit + {:blur? true + :icon :i/edit :accessibility-label :rename-key-pair :label (i18n/label :t/rename-key-pair) :on-press on-rename-keypair} - {:icon :i/delete + {:blur? true + :icon :i/delete :accessibility-label :remove-key-pair :add-divider? true :danger? true diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs index 3978f90277..df20708f05 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs @@ -11,13 +11,16 @@ [] (let [keypairs-key-uids (rf/sub [:get-screen-params]) on-success-scan (rn/use-callback (fn [scanned-text] - (rf/dispatch [:wallet/success-keypair-qr-scan scanned-text - keypairs-key-uids]) + (rf/dispatch [:wallet/success-keypair-qr-scan + scanned-text + keypairs-key-uids + [:navigate-back]]) [keypairs-key-uids]))] [scan-qr-code/view {:title (i18n/label :t/scan-key-pairs-qr-code) :subtitle (i18n/label :t/find-it-in-setting) :share-button? false + :import-keypair? true :validate-fn sync-utils/valid-connection-string? - :error-message (i18n/label :t/invalid-qr) + :error-message (i18n/label :t/invalid-key-pair-qr) :on-success-scan on-success-scan}])) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/style.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/style.cljs index ae4d0edb8a..27e0142baa 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/style.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/style.cljs @@ -4,7 +4,8 @@ {:margin-bottom 8}) (def bottom-action - {:margin-horizontal -20}) + {:margin-horizontal -20 + :margin-vertical -12}) (def error-container {:margin-left 20 diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/view.cljs index 8836d1d06f..15293664f0 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/view.cljs @@ -2,6 +2,7 @@ (:require [clojure.string :as string] [quo.core :as quo] [react-native.core :as rn] + [react-native.safe-area :as safe-area] [status-im.common.floating-button-page.view :as floating-button-page] [status-im.common.validation.keypair :as keypair-validator] [status-im.constants :as constants] @@ -14,19 +15,24 @@ (defn view [] - (let [{:keys [name key-uid]} (rf/sub [:get-screen-params]) + (let [insets (safe-area/get-insets) + {existing-keypair-name :name + :keys [key-uid]} (rf/sub [:get-screen-params]) + existing-keypair-names (rf/sub [:wallet/keypair-names]) customization-color (rf/sub [:profile/customization-color]) - [unsaved-keypair-name set-unsaved-keypair-name] (rn/use-state name) + [unsaved-keypair-name set-unsaved-keypair-name] (rn/use-state existing-keypair-name) [error-msg set-error-msg] (rn/use-state nil) [typing? set-typing?] (rn/use-state false) validate-keypair-name (rn/use-callback (debounce/debounce - (fn [name] + (fn [input-name] (set-error-msg (keypair-validator/validation-keypair-name - name)) + input-name + existing-keypair-names)) (set-typing? false)) - 300)) + 300) + [existing-keypair-names]) on-change-text (rn/use-callback (fn [text] (set-typing? true) (set-unsaved-keypair-name @@ -40,45 +46,57 @@ :keypair-name unsaved-keypair-name}]) [unsaved-keypair-name key-uid])] - [floating-button-page/view - {:header [quo/page-nav - {:icon-name :i/close - :on-press navigate-back - :accessibility-label :top-bar}] - :footer [quo/bottom-actions - {:actions :one-action - :button-one-label (i18n/label :t/save) - :button-one-props {:disabled? (or typing? - (string/blank? unsaved-keypair-name) - (not (string/blank? error-msg))) - :customization-color customization-color - :on-press on-save} - :container-style style/bottom-action}]} - [quo/page-top - {:container-style style/header-container - :title (i18n/label :t/rename-key-pair) - :description :context-tag - :context-tag {:type :icon - :size 24 - :context name - :icon :i/seed-phrase}}] - [quo/input - {:container-style {:margin-horizontal 20} - :placeholder (i18n/label :t/keypair-name-input-placeholder) - :label (i18n/label :t/keypair-name) - :default-value unsaved-keypair-name - :char-limit constants/key-pair-name-max-length - :max-length constants/key-pair-name-max-length - :auto-focus true - :clearable? (not (string/blank? unsaved-keypair-name)) - :on-clear on-clear - :on-change-text on-change-text - :error? (not (string/blank? error-msg))}] - (when-not (string/blank? error-msg) - [quo/info-message - {:type :error - :size :default - :icon :i/info - :container-style style/error-container} - error-msg])])) + [quo/overlay {:type :shell} + [floating-button-page/view + {:footer-container-padding 0 + :blur? true + :header [quo/page-nav + {:margin-top (:top insets) + :icon-name :i/close + :background :blur + :on-press navigate-back + :accessibility-label :top-bar}] + :footer [quo/bottom-actions + {:actions :one-action + :blur? true + :button-one-label (i18n/label :t/save) + :button-one-props {:blur? true + :disabled? (or typing? + (= existing-keypair-name + unsaved-keypair-name) + (string/blank? + unsaved-keypair-name) + (not (string/blank? + error-msg))) + :customization-color customization-color + :on-press on-save} + :container-style style/bottom-action}]} + [quo/page-top + {:container-style style/header-container + :title (i18n/label :t/rename-key-pair) + :description :context-tag + :blur? true + :context-tag {:type :icon + :size 24 + :context existing-keypair-name + :icon :i/seed-phrase}}] + [quo/input + {:blur? true + :container-style {:margin-horizontal 20} + :placeholder (i18n/label :t/keypair-name-input-placeholder) + :label (i18n/label :t/keypair-name) + :default-value unsaved-keypair-name + :char-limit constants/key-pair-name-max-length + :auto-focus true + :clearable? (not (string/blank? unsaved-keypair-name)) + :on-clear on-clear + :on-change-text on-change-text + :error? (not (string/blank? error-msg))}] + (when-not (string/blank? error-msg) + [quo/info-message + {:type :error + :size :default + :icon :i/info + :container-style style/error-container} + error-msg])]])) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/view.cljs index cf2e8a33b9..97a159a2f7 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/view.cljs @@ -1,11 +1,11 @@ (ns status-im.contexts.settings.wallet.keypairs-and-accounts.view (:require [quo.core :as quo] - [quo.foundations.colors :as colors] [quo.theme] [react-native.core :as rn] [react-native.safe-area :as safe-area] [status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view :as actions] [status-im.contexts.settings.wallet.keypairs-and-accounts.style :as style] + [status-im.feature-flags :as ff] [utils.address :as utils] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -17,13 +17,12 @@ (defn on-options-press [{:keys [drawer-props keypair]}] (rf/dispatch [:show-bottom-sheet - {:content (fn [] [actions/view - {:drawer-props drawer-props - :keypair keypair}]) + {:content (fn [] [actions/view + {:drawer-props drawer-props + :keypair keypair}]) - :blur-background colors/bottom-sheet-background-blur - :theme (:theme drawer-props) - :shell? true}])) + :theme (:theme drawer-props) + :shell? true}])) (defn options-drawer-props [{{:keys [name]} :keypair @@ -70,7 +69,7 @@ {:blur? true :status-indicator false :stored :on-device - :action :options + :action (if default-keypair? :none :options) :accounts accounts :customization-color customization-color :container-style style/keypair-container-style @@ -83,17 +82,16 @@ (defn on-missing-keypair-options-press [_event keypair-data] (rf/dispatch [:show-bottom-sheet - {:theme :dark - :shell? true - :blur-background colors/bottom-sheet-background-blur - :content (fn [] [actions/view - {:keypair keypair-data - :drawer-props (options-drawer-props - {:theme :dark - :type :keypair - :stored :missing - :blur? true - :keypair keypair-data})}])}])) + {:theme :dark + :shell? true + :content (fn [] [actions/view + {:keypair keypair-data + :drawer-props (options-drawer-props + {:theme :dark + :type :keypair + :stored :missing + :blur? true + :keypair keypair-data})}])}])) (defn view [] @@ -127,6 +125,7 @@ :header (when (seq missing-keypairs) [quo/missing-keypairs {:blur? true + :show-import-all? (ff/enabled? ::ff/settings.import-all-keypairs) :keypairs missing-keypairs :on-import-press on-import-press :container-style style/missing-keypairs-container-style diff --git a/src/status_im/contexts/settings/wallet/network_settings/view.cljs b/src/status_im/contexts/settings/wallet/network_settings/view.cljs index 8f11afc0af..5058abd8b2 100644 --- a/src/status_im/contexts/settings/wallet/network_settings/view.cljs +++ b/src/status_im/contexts/settings/wallet/network_settings/view.cljs @@ -1,6 +1,5 @@ (ns status-im.contexts.settings.wallet.network-settings.view (:require [quo.core :as quo] - [quo.foundations.colors :as colors] [quo.foundations.resources :as resources] [quo.theme] [react-native.core :as rn] @@ -80,12 +79,11 @@ (defn on-change-testnet [{:keys [enable? blur? theme]}] (rf/dispatch [:show-bottom-sheet - {:content (fn [] [testnet/view - {:enable? enable? - :blur? blur?}]) - :theme theme - :shell? blur? - :blur-background colors/bottom-sheet-background-blur}])) + {:content (fn [] [testnet/view + {:enable? enable? + :blur? blur?}]) + :theme theme + :shell? blur?}])) (defn view [] diff --git a/src/status_im/contexts/settings/wallet/saved_addresses/sheets/address_options/view.cljs b/src/status_im/contexts/settings/wallet/saved_addresses/sheets/address_options/view.cljs index 0fa354a19e..f0dc8e39a0 100644 --- a/src/status_im/contexts/settings/wallet/saved_addresses/sheets/address_options/view.cljs +++ b/src/status_im/contexts/settings/wallet/saved_addresses/sheets/address_options/view.cljs @@ -2,7 +2,6 @@ (:require [clojure.string :as string] [quo.core :as quo] - [quo.foundations.colors :as colors] [react-native.core :as rn] [react-native.platform :as platform] [status-im.constants :as constants] @@ -52,11 +51,10 @@ open-remove-confirmation-sheet (rn/use-callback #(rf/dispatch [:show-bottom-sheet - {:theme :dark - :shell? true - :blur-background colors/bottom-sheet-background-blur - :content (fn [] - [remove-address/view opts])}]) + {:theme :dark + :shell? true + :content (fn [] + [remove-address/view opts])}]) [opts]) open-show-address-qr (rn/use-callback #(rf/dispatch [:open-modal diff --git a/src/status_im/contexts/settings/wallet/wallet_options/view.cljs b/src/status_im/contexts/settings/wallet/wallet_options/view.cljs index 67cbc20d8f..58153e98c5 100644 --- a/src/status_im/contexts/settings/wallet/wallet_options/view.cljs +++ b/src/status_im/contexts/settings/wallet/wallet_options/view.cljs @@ -16,11 +16,10 @@ (defn basic-settings-options [] - [(when (ff/enabled? ::ff/settings.keypairs-and-accounts) - {:title (i18n/label :t/keypairs-and-accounts) - :blur? true - :on-press open-keypairs-and-accounts-settings-modal - :action :arrow}) + [{:title (i18n/label :t/keypairs-and-accounts) + :blur? true + :on-press open-keypairs-and-accounts-settings-modal + :action :arrow} (when (ff/enabled? ::ff/settings.saved-addresses) {:title (i18n/label :t/saved-addresses) :blur? true @@ -74,7 +73,5 @@ [quo/page-top {:title (i18n/label :t/wallet) :title-accessibility-label :wallet-settings-header}] - (when (or (ff/enabled? ::ff/settings.keypairs-and-accounts) - (ff/enabled? ::ff/settings.saved-addresses)) - [basic-settings]) + [basic-settings] [advanced-settings]])) diff --git a/src/status_im/contexts/wallet/effects.cljs b/src/status_im/contexts/wallet/effects.cljs index 8c0fedae29..e2fe3c4147 100644 --- a/src/status_im/contexts/wallet/effects.cljs +++ b/src/status_im/contexts/wallet/effects.cljs @@ -73,7 +73,7 @@ (fn [resolver rejecter] (json-rpc/call {:method "accounts_makeSeedPhraseKeypairFullyOperable" :params [(security/safe-unmask-data mnemonic) - (-> password security/safe-unmask-data native-module/sha3)] + (security/safe-unmask-data password)] :on-error (fn [error] (rejecter (ex-info (str error) {:error error}))) :on-success (fn [value] diff --git a/src/status_im/contexts/wallet/events.cljs b/src/status_im/contexts/wallet/events.cljs index 0ab6654e7e..5b751cf6d2 100644 --- a/src/status_im/contexts/wallet/events.cljs +++ b/src/status_im/contexts/wallet/events.cljs @@ -529,18 +529,17 @@ :wallet/process-keypair-from-backup (fn [{:keys [db]} [{:keys [backedUpKeypair]}]] (let [{:keys [key-uid accounts]} backedUpKeypair - updated-keypairs (assoc-in db - [:wallet :keypairs key-uid] - (data-store/rpc->keypair backedUpKeypair)) - accounts-fx (mapv (fn [{:keys [chat] :as account}] - ;; We exclude the chat account from the profile keypair - ;; for fetching the assets - (when-not chat - [:dispatch - [:wallet/process-account-from-signal - account]])) - accounts)] - {:db (assoc-in db [:wallet :keypairs] updated-keypairs) + accounts-fx + (mapv (fn [{:keys [chat] :as account}] + ;; We exclude the chat account from the profile keypair for fetching the assets + (when-not chat + [:dispatch + [:wallet/process-account-from-signal + account]])) + accounts)] + {:db (assoc-in db + [:wallet :keypairs key-uid] + (data-store/rpc->keypair backedUpKeypair)) :fx accounts-fx}))) (rf/reg-event-fx diff --git a/src/status_im/feature_flags.cljs b/src/status_im/feature_flags.cljs index 48670c02bb..cd83ce2398 100644 --- a/src/status_im/feature_flags.cljs +++ b/src/status_im/feature_flags.cljs @@ -11,10 +11,10 @@ (def ^:private initial-flags {::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED) - ::settings.keypairs-and-accounts (enabled-in-env? - :FLAG_WALLET_SETTINGS_KEYPAIRS_AND_ACCOUNTS_ENABLED) ::settings.saved-addresses (enabled-in-env? :FLAG_WALLET_SETTINGS_SAVED_ADDRESSES_ENABLED) + ::settings.import-all-keypairs (enabled-in-env? + :FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS) ::shell.jump-to (enabled-in-env? :ENABLE_JUMP_TO) ::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING) ::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 363de5202f..9b83b4441d 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -542,7 +542,7 @@ :component wallet-options/view} {:name :screen/settings.rename-keypair - :options (assoc options/dark-screen :sheet? true) + :options options/transparent-screen-options :component keypair-rename/view} {:name :screen/settings.encrypted-keypair-qr @@ -558,7 +558,7 @@ :component keypairs-and-accounts/view} {:name :screen/settings.scan-keypair-qr - :options options/transparent-modal-screen-options + :options options/transparent-screen-options :component scan-keypair-qr/view} {:name :screen/settings.missing-keypair.import-seed-phrase diff --git a/src/status_im/subs/wallet/wallet.cljs b/src/status_im/subs/wallet/wallet.cljs index b83496e5e3..e481c1c7fb 100644 --- a/src/status_im/subs/wallet/wallet.cljs +++ b/src/status_im/subs/wallet/wallet.cljs @@ -205,6 +205,12 @@ (fn [{:keys [keypairs]}] (vals keypairs))) +(rf/reg-sub + :wallet/keypair-names + :<- [:wallet/keypairs-list] + (fn [keypairs] + (set (map :name keypairs)))) + (rf/reg-sub :wallet/selected-keypair-uid :<- [:wallet/create-account] @@ -244,7 +250,7 @@ size 32}}] (->> accounts (keep (fn [{:keys [path color emoji name address]}] - (when-not (string/starts-with? path constants/path-eip1581) + (when-not (string/starts-with? (str path) constants/path-eip1581) {:account-props {:customization-color color :size size :emoji emoji diff --git a/src/status_im/subs/wallet/wallet_test.cljs b/src/status_im/subs/wallet/wallet_test.cljs index 2989f29adb..546cf798c6 100644 --- a/src/status_im/subs/wallet/wallet_test.cljs +++ b/src/status_im/subs/wallet/wallet_test.cljs @@ -643,18 +643,20 @@ :removed false}) (def profile-key-pair-key-uid "abc") +(def profile-key-pair-name "My Profile") (def seed-phrase-key-pair-key-uid "def") +(def seed-phrase-key-pair-name "My Key Pair") (def profile-keypair {:key-uid profile-key-pair-key-uid - :name "My Profile" + :name profile-key-pair-name :type :profile :lowest-operability :fully :accounts []}) (def seed-phrase-keypair {:key-uid seed-phrase-key-pair-key-uid - :name "My Key Pair" + :name seed-phrase-key-pair-name :type :seed :lowest-operability :no :accounts []}) @@ -676,6 +678,14 @@ (is (= 2 (count result))) (is (match? expected result)))) +(h/deftest-sub :wallet/keypair-names + [sub-name] + (swap! rf-db/app-db assoc-in + [:wallet :keypairs] + {profile-key-pair-key-uid profile-keypair + seed-phrase-key-pair-key-uid seed-phrase-keypair}) + (is (match? #{seed-phrase-key-pair-name profile-key-pair-name} (rf/sub [sub-name])))) + (h/deftest-sub :wallet/settings-keypairs-accounts [sub-name] (testing "returns formatted key-pairs and accounts" diff --git a/translations/en.json b/translations/en.json index f6bb549e2d..143f3a7d0e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1302,6 +1302,8 @@ "scan-with-status-app": "Scan with the Status app on another device", "scan-key-pairs-qr-code": "Scan key pairs QR code", "invalid-qr": "Oops! This QR doesn’t 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", "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.", @@ -2639,6 +2641,7 @@ "max": "Max: {{number}}", "your-key-pair-name-is-too-long": "Your key pair name is too long", "your-key-pair-name-is-too-short": "Your key pair name is too short", + "key-name-error-taken": "Key pair name already in use", "key-name-error-length": "Key name too long", "key-name-error-emoji": "Emojis are not allowed", "key-name-error-special-char": "Special characters are not allowed", From e2e8afb7b1a80a20d08c311568f49f2d3387f5bb Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 26 Jun 2024 14:45:43 +0200 Subject: [PATCH 07/10] WC signing/sending transactions flow (#20445) * WC signing transactions flow * Fixes * Fixes * Post-review fixes * Removed leftover * Post-review fixes * Fixes * Fixes * Test fixes --- src/quo/components/list_items/dapp/style.cljs | 3 +- src/quo/components/list_items/dapp/view.cljs | 14 ++-- .../components/tags/summary_tag/style.cljs | 5 ++ src/quo/components/tags/summary_tag/view.cljs | 6 +- .../common/raw_data_block/style.cljs | 13 +-- src/status_im/common/raw_data_block/view.cljs | 2 +- src/status_im/constants.cljs | 6 ++ .../preview/quo/tags/summary_tag.cljs | 4 +- .../wallet/common/account_switcher/view.cljs | 3 +- .../wallet/common/utils/networks.cljs | 39 +++++++++ .../send/input_amount/component_spec.cljs | 2 + .../contexts/wallet/wallet_connect/core.cljs | 27 +++++- .../wallet/wallet_connect/events.cljs | 8 +- .../modals/common/data_block/view.cljs | 8 ++ .../modals/common/footer/style.cljs | 18 ++++ .../modals/common/footer/view.cljs | 35 ++++++++ .../modals/common/header/style.cljs | 10 +++ .../modals/common/header/view.cljs | 26 ++++++ .../wallet_connect/modals/common/style.cljs | 23 ++++++ .../modals/send_transaction/view.cljs | 63 ++++++++++++++ .../modals/sign_message/view.cljs | 42 ++++++++++ .../modals/sign_transaction/view.cljs | 63 ++++++++++++++ .../wallet_connect/processing_events.cljs | 49 ++++++++--- .../wallet_connect/responding_events.cljs | 60 +++++++++++++- .../wallet_connect/sign_message/style.cljs | 29 ------- .../wallet_connect/sign_message/view.cljs | 82 ------------------- src/status_im/navigation/screens.cljs | 14 +++- src/status_im/subs/wallet/networks.cljs | 41 +--------- src/status_im/subs/wallet/networks_test.cljs | 7 ++ src/status_im/subs/wallet/wallet_connect.cljs | 78 +++++++++++++++++- src/status_im/subs/wallet/wallet_test.cljs | 3 + translations/en.json | 10 ++- 32 files changed, 598 insertions(+), 195 deletions(-) create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/common/data_block/view.cljs create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/common/footer/style.cljs create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/common/footer/view.cljs create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/common/header/style.cljs create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/common/header/view.cljs create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/common/style.cljs create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/send_transaction/view.cljs create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/sign_message/view.cljs create mode 100644 src/status_im/contexts/wallet/wallet_connect/modals/sign_transaction/view.cljs delete mode 100644 src/status_im/contexts/wallet/wallet_connect/sign_message/style.cljs delete mode 100644 src/status_im/contexts/wallet/wallet_connect/sign_message/view.cljs diff --git a/src/quo/components/list_items/dapp/style.cljs b/src/quo/components/list_items/dapp/style.cljs index d7ab20afd6..d9f67b62b4 100644 --- a/src/quo/components/list_items/dapp/style.cljs +++ b/src/quo/components/list_items/dapp/style.cljs @@ -34,7 +34,8 @@ (def container-info {:flex-direction :row - :align-items :center}) + :align-items :center + :flex 1}) (def user-info {:margin-left 8}) diff --git a/src/quo/components/list_items/dapp/view.cljs b/src/quo/components/list_items/dapp/view.cljs index efe707e0d5..0626158480 100644 --- a/src/quo/components/list_items/dapp/view.cljs +++ b/src/quo/components/list_items/dapp/view.cljs @@ -25,14 +25,16 @@ :style {:width 32 :height 32}}] [rn/view {:style style/user-info} [text/text - {:weight :semi-bold - :size :paragraph-1 - :style (style/style-text-name theme)} + {:weight :semi-bold + :size :paragraph-1 + :number-of-lines 1 + :style (style/style-text-name theme)} (:name dapp)] [text/text - {:weight :regular - :size :paragraph-2 - :style (style/style-text-value theme)} + {:weight :regular + :size :paragraph-2 + :number-of-lines 1 + :style (style/style-text-value theme)} (:value dapp)]]] (when right-component [right-component dapp])])) diff --git a/src/quo/components/tags/summary_tag/style.cljs b/src/quo/components/tags/summary_tag/style.cljs index f33654ff82..4f3922276b 100644 --- a/src/quo/components/tags/summary_tag/style.cljs +++ b/src/quo/components/tags/summary_tag/style.cljs @@ -28,5 +28,10 @@ :height 24 :border-radius 12}) +(def dapp + {:width 24 + :height 24 + :border-radius 12}) + (def token-image {:border-radius 12}) diff --git a/src/quo/components/tags/summary_tag/view.cljs b/src/quo/components/tags/summary_tag/view.cljs index c652c5a17d..40b0df5b37 100644 --- a/src/quo/components/tags/summary_tag/view.cljs +++ b/src/quo/components/tags/summary_tag/view.cljs @@ -23,6 +23,10 @@ [rn/image {:source image-source :style style/network}] + :dapp + [rn/image + {:source image-source + :style style/dapp}] :saved-address [wallet-user-avatar/wallet-user-avatar {:full-name label @@ -50,7 +54,7 @@ - :label - string - tag label - :customization-color - color - It will be passed down to components that should vary based on a custom color. - - :type - :token / :user / :collectible / :saved-address / :network / :account + - :type - :token / :user / :collectible / :saved-address / :network / :account / :dapp - :emoji - string - emoji used for displaying account avatar - :image-source - resource - image to display on :network, :collectible and :user - :theme - :light / :dark" diff --git a/src/status_im/common/raw_data_block/style.cljs b/src/status_im/common/raw_data_block/style.cljs index d3ef6279f3..bd0c94dcb6 100644 --- a/src/status_im/common/raw_data_block/style.cljs +++ b/src/status_im/common/raw_data_block/style.cljs @@ -2,12 +2,13 @@ (:require [quo.foundations.colors :as colors])) (def container - {:flex 1 - :padding 10 - :margin-vertical 10.5 - :border-width 1 - :border-color colors/neutral-10 - :border-radius 16}) + {:flex 1 + :padding 10 + :margin-top 10.5 + :margin-bottom 0 + :border-width 1 + :border-color colors/neutral-10 + :border-radius 16}) (def content {:padding-bottom 20}) diff --git a/src/status_im/common/raw_data_block/view.cljs b/src/status_im/common/raw_data_block/view.cljs index 64fc506815..ec99ecf73d 100644 --- a/src/status_im/common/raw_data_block/view.cljs +++ b/src/status_im/common/raw_data_block/view.cljs @@ -4,7 +4,7 @@ [status-im.common.raw-data-block.style :as style])) (defn view - [{:keys [data]}] + [data] [rn/scroll-view {:style style/container :content-container-style style/content} diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index be6c66b8a2..9c0c4f7da1 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -268,12 +268,14 @@ (def ^:const wallet-connect-personal-sign-method "personal_sign") (def ^:const wallet-connect-eth-sign-method "eth_sign") (def ^:const wallet-connect-eth-send-transaction-method "eth_sendTransaction") +(def ^:const wallet-connect-eth-sign-transaction-method "eth_signTransaction") (def ^:const wallet-connect-eth-sign-typed-method "eth_signTypedData") (def ^:const wallet-connect-eth-sign-typed-v4-method "eth_signTypedData_v4") (def ^:const wallet-connect-supported-methods #{wallet-connect-personal-sign-method wallet-connect-eth-sign-method wallet-connect-eth-send-transaction-method + wallet-connect-eth-sign-transaction-method wallet-connect-eth-sign-typed-method wallet-connect-eth-sign-typed-v4-method}) (def ^:const wallet-connect-supported-events #{"accountsChanged" "chainChanged"}) @@ -492,6 +494,10 @@ (def ^:const optimism-abbreviated-name "Oeth.") (def ^:const arbitrum-abbreviated-name "Arb1.") +(def ^:const mainnet-full-name "Mainnet") +(def ^:const optimism-full-name "Optimism") +(def ^:const arbitrum-full-name "Arbitrum") + (def ^:const mainnet-network-name :mainnet) (def ^:const ethereum-network-name :ethereum) (def ^:const optimism-network-name :optimism) diff --git a/src/status_im/contexts/preview/quo/tags/summary_tag.cljs b/src/status_im/contexts/preview/quo/tags/summary_tag.cljs index 1d496667c5..9344e78871 100644 --- a/src/status_im/contexts/preview/quo/tags/summary_tag.cljs +++ b/src/status_im/contexts/preview/quo/tags/summary_tag.cljs @@ -51,7 +51,9 @@ {:value "Saved address" :key :saved-address} {:value "Account" - :key :account}]}]) + :key :account} + {:value "Dapp" + :key :dapp}]}]) (defn view [] diff --git a/src/status_im/contexts/wallet/common/account_switcher/view.cljs b/src/status_im/contexts/wallet/common/account_switcher/view.cljs index 17ab23c194..add88c3417 100644 --- a/src/status_im/contexts/wallet/common/account_switcher/view.cljs +++ b/src/status_im/contexts/wallet/common/account_switcher/view.cljs @@ -4,7 +4,6 @@ [status-im.contexts.wallet.sheets.account-options.view :as account-options] [status-im.contexts.wallet.sheets.network-filter.view :as network-filter] [status-im.contexts.wallet.sheets.select-account.view :as select-account] - [status-im.feature-flags :as ff] [utils.re-frame :as rf])) (defn get-bottom-sheet-args @@ -37,7 +36,7 @@ :networks networks :align-center? true :networks-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}]) - :right-side [(when (and (ff/enabled? ::ff/wallet.wallet-connect) + :right-side [(when (and true (not watch-only?)) {:icon-name :i/dapps :on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])}) diff --git a/src/status_im/contexts/wallet/common/utils/networks.cljs b/src/status_im/contexts/wallet/common/utils/networks.cljs index 9cfae084eb..188f4e1e67 100644 --- a/src/status_im/contexts/wallet/common/utils/networks.cljs +++ b/src/status_im/contexts/wallet/common/utils/networks.cljs @@ -1,5 +1,6 @@ (ns status-im.contexts.wallet.common.utils.networks (:require [clojure.string :as string] + [quo.foundations.resources :as resources] [status-im.constants :as constants] [utils.number])) @@ -141,3 +142,41 @@ (let [token-networks-ids (mapv #(:chain-id %) token-networks) token-networks-ids-set (set token-networks-ids)] (contains? token-networks-ids-set chain-id))) + +(def mainnet-network-details + {:source (resources/get-network constants/mainnet-network-name) + :short-name constants/mainnet-short-name + :full-name constants/mainnet-full-name + :network-name constants/mainnet-network-name + :abbreviated-name constants/mainnet-abbreviated-name}) + +(def arbitrum-network-details + {:source (resources/get-network constants/arbitrum-network-name) + :short-name constants/arbitrum-short-name + :full-name constants/arbitrum-full-name + :network-name constants/arbitrum-network-name + :abbreviated-name constants/arbitrum-abbreviated-name}) + +(def optimism-network-details + {:source (resources/get-network constants/optimism-network-name) + :short-name constants/optimism-short-name + :full-name constants/optimism-full-name + :network-name constants/optimism-network-name + :abbreviated-name constants/optimism-abbreviated-name}) + +(defn get-network-details + [chain-id] + (condp contains? chain-id + #{constants/ethereum-mainnet-chain-id constants/ethereum-goerli-chain-id + constants/ethereum-sepolia-chain-id} + mainnet-network-details + + #{constants/arbitrum-mainnet-chain-id constants/arbitrum-goerli-chain-id + constants/arbitrum-sepolia-chain-id} + arbitrum-network-details + + #{constants/optimism-mainnet-chain-id constants/optimism-goerli-chain-id + constants/optimism-sepolia-chain-id} + optimism-network-details + + nil)) diff --git a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs index 0162bd0da7..ad9f150c7d 100644 --- a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs @@ -47,6 +47,7 @@ :network-name :mainnet :abbreviated-name "Eth." + :full-name "Mainnet" :chain-id 1 :related-chain-id 1 :layer 1}] @@ -92,6 +93,7 @@ :short-name "eth" :network-name :mainnet :abbreviated-name "Eth." + :full-name "Mainnet" :chain-id 1 :related-chain-id 1 :layer 1}] diff --git a/src/status_im/contexts/wallet/wallet_connect/core.cljs b/src/status_im/contexts/wallet/wallet_connect/core.cljs index 4de3f399c9..e48f1fd4d7 100644 --- a/src/status_im/contexts/wallet/wallet_connect/core.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/core.cljs @@ -1,8 +1,19 @@ (ns status-im.contexts.wallet.wallet-connect.core - (:require [native-module.core :as native-module] + (:require [clojure.edn :as edn] + [clojure.string :as string] + [native-module.core :as native-module] + [status-im.constants :as constants] [utils.security.core :as security] [utils.transforms :as transforms])) +(def method-to-screen + {constants/wallet-connect-personal-sign-method :screen/wallet-connect.sign-message + constants/wallet-connect-eth-sign-typed-method :screen/wallet-connect.sign-message + constants/wallet-connect-eth-sign-method :screen/wallet-connect.sign-message + constants/wallet-connect-eth-sign-typed-v4-method :screen/wallet-connect.sign-message + constants/wallet-connect-eth-send-transaction-method :screen/wallet-connect.send-transaction + constants/wallet-connect-eth-sign-transaction-method :screen/wallet-connect.sign-transaction}) + (defn extract-native-call-signature [data] (-> data transforms/json->clj :result)) @@ -11,6 +22,13 @@ [chain-id] (str "eip155:" chain-id)) +(defn eip155->chain-id + [chain-id-str] + (-> chain-id-str + (string/split #":") + last + edn/read-string)) + (defn format-eip155-address [address chain-id] (str chain-id ":" address)) @@ -23,9 +41,14 @@ [event] (get-in event [:params :request :params])) +(defn get-db-current-request-event + [db] + (get-in db [:wallet-connect/current-request :event])) + (defn get-db-current-request-params [db] - (-> (get-in db [:wallet-connect/current-request :event]) + (-> db + get-db-current-request-event get-request-params)) (def ^:private sign-typed-data-by-version diff --git a/src/status_im/contexts/wallet/wallet_connect/events.cljs b/src/status_im/contexts/wallet/wallet_connect/events.cljs index 8dba642f7f..2c7fdc1dd6 100644 --- a/src/status_im/contexts/wallet/wallet_connect/events.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/events.cljs @@ -70,7 +70,7 @@ {:db (dissoc db :wallet-connect/current-proposal)})) (rf/reg-event-fx - :wallet-connect/reset-current-session-request + :wallet-connect/reset-current-request (fn [{:keys [db]}] {:db (dissoc db :wallet-connect/current-request)})) @@ -107,12 +107,6 @@ :on-fail #(log/error "Failed to pair with dApp" {:error %}) :on-success #(log/info "dApp paired successfully")}]]}))) -(rf/reg-event-fx - :wallet-connect/close-session-request - (fn [_ _] - {:fx [[:dispatch [:dismiss-modal :screen/wallet.wallet-connect-session-proposal]] - [:dispatch [:wallet-connect/reset-current-session-request]]]})) - (rf/reg-event-fx :wallet-connect/fetch-active-sessions (fn [{:keys [db]}] diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/data_block/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/data_block/view.cljs new file mode 100644 index 0000000000..eb2ce66499 --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/data_block/view.cljs @@ -0,0 +1,8 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.common.data-block.view + (:require [status-im.common.raw-data-block.view :as raw-data-block] + [utils.re-frame :as rf])) + +(defn view + [] + (let [display-data (rf/sub [:wallet-connect/current-request-display-data])] + [raw-data-block/view display-data])) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/style.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/style.cljs new file mode 100644 index 0000000000..562df9ee80 --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/style.cljs @@ -0,0 +1,18 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.common.footer.style) + +(def content-container + {:padding-horizontal 20}) + +(def data-items-container + {:flex-direction :row + :padding-top 12 + :padding-bottom 4 + :gap 16}) + +(def auth-container + {:height 48 + :margin-vertical 12}) + +(def warning-container + {:align-items :center + :margin-bottom 12}) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/view.cljs new file mode 100644 index 0000000000..4d422c1bf9 --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/footer/view.cljs @@ -0,0 +1,35 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.common.footer.view + (:require [quo.core :as quo] + [quo.foundations.colors :as colors] + [react-native.core :as rn] + [status-im.common.standard-authentication.core :as standard-authentication] + [status-im.contexts.wallet.wallet-connect.modals.common.footer.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn- on-auth-success + [password] + (rf/dispatch [:hide-bottom-sheet]) + (rf/dispatch [:wallet-connect/respond-current-session password])) + +(defn view + [{:keys [warning-label slide-button-text disabed?]} & children] + (let [{:keys [customization-color]} (rf/sub [:wallet-connect/current-request-account-details])] + [rn/view {:style style/content-container} + (into [rn/view + {:style style/data-items-container}] + children) + [rn/view {:style style/auth-container} + [standard-authentication/slide-button + {:size :size-48 + :track-text slide-button-text + :disabled? disabed? + :customization-color customization-color + :on-auth-success on-auth-success + :auth-button-label (i18n/label :t/confirm)}]] + [rn/view {:style style/warning-container} + [quo/text + {:size :paragraph-2 + :style {:color colors/neutral-80-opa-70} + :weight :medium} + warning-label]]])) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/header/style.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/header/style.cljs new file mode 100644 index 0000000000..fe984094af --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/header/style.cljs @@ -0,0 +1,10 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.common.header.style) + +(def header-container + {:padding-vertical 12}) + +(def header-dapp-name + {:margin-top -4}) + +(def header-account-name + {:padding-top 4}) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/header/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/header/view.cljs new file mode 100644 index 0000000000..991949fcaa --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/header/view.cljs @@ -0,0 +1,26 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.common.header.view + (:require [quo.core :as quo] + [react-native.core :as rn] + [status-im.contexts.wallet.wallet-connect.modals.common.header.style :as style])) + +(defn view + [{:keys [label dapp account]}] + [rn/view + {:style style/header-container} + [quo/text + {:size :heading-1 + :weight :semi-bold} + (let [{:keys [name icons]} (:peerMetadata dapp)] + [rn/view {:style style/header-dapp-name} + [quo/summary-tag + {:type :dapp + :label name + :image-source (first icons)}]]) + (str " " label " ") + (let [{:keys [emoji customization-color name]} account] + [rn/view {:style style/header-account-name} + [quo/summary-tag + {:type :account + :emoji emoji + :label name + :customization-color customization-color}]])]]) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/style.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/style.cljs new file mode 100644 index 0000000000..d120b68d35 --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/style.cljs @@ -0,0 +1,23 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.common.style + (:require [status-im.constants :as constants])) + +(defn container + [bottom] + {:position :absolute + :bottom bottom + :top 0 + :left 0 + :right 0 + :padding-top constants/sheet-screen-handle-height}) + +(def data-content-container + {:flex 1 + :padding-horizontal 20}) + +(def sign-message-content-container + (merge data-content-container + {:margin-bottom 10.5})) + +(def data-item + {:flex 1 + :background-color :transparent}) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/send_transaction/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/send_transaction/view.cljs new file mode 100644 index 0000000000..6f74cb6676 --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/send_transaction/view.cljs @@ -0,0 +1,63 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.send-transaction.view + (:require [quo.core :as quo] + [react-native.core :as rn] + [react-native.safe-area :as safe-area] + [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.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn view + [] + (let [bottom (safe-area/get-bottom) + {:keys [customization-color] + :as account} (rf/sub [:wallet-connect/current-request-account-details]) + dapp (rf/sub [:wallet-connect/current-request-dapp]) + network (rf/sub [:wallet-connect/current-request-network]) + {:keys [max-fees-fiat-formatted + 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}] + [rn/view {:flex 1} + [rn/view {:style style/data-content-container} + [header/view + {:label (i18n/label :t/wallet-connect-send-transaction-header) + :dapp dapp + :account account}] + [data-block/view]] + (when error-state + [quo/alert-banner + {:action? false + :text (i18n/label (condp = error-state + :not-enough-assets-to-pay-gas-fees + :t/not-enough-assets-to-pay-gas-fees + + :not-enough-assets + :t/not-enough-assets))}]) + [footer/view + {:warning-label (i18n/label :t/wallet-connect-send-transaction-warning) + :slide-button-text (i18n/label :t/slide-to-send) + :disabled? error-state} + [quo/data-item + {:status :default + :card? false + :container-style style/data-item + :title (i18n/label :t/network) + :subtitle-type :network + :network-image (:source network) + :subtitle (:full-name network)}] + [quo/data-item + {:size :small + :status :default + :card? false + :container-style style/data-item + :title (i18n/label :t/max-fees) + :subtitle (or max-fees-fiat-formatted (i18n/label :t/no-fees))}]]]])) + diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/sign_message/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/sign_message/view.cljs new file mode 100644 index 0000000000..ac631677ef --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/sign_message/view.cljs @@ -0,0 +1,42 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.sign-message.view + (:require [quo.core :as quo] + [react-native.core :as rn] + [react-native.safe-area :as safe-area] + [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.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn view + [] + (let [bottom (safe-area/get-bottom) + {:keys [customization-color] + :as account} (rf/sub [:wallet-connect/current-request-account-details]) + 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}] + [rn/view {:flex 1} + [rn/view {:style style/sign-message-content-container} + [header/view + {:label (i18n/label :t/wallet-connect-sign-message-header) + :dapp dapp + :account account}] + [data-block/view]] + [footer/view + {:warning-label (i18n/label :t/wallet-connect-sign-message-warning) + :slide-button-text (i18n/label :t/slide-to-sign)} + [quo/data-item + {:size :small + :status :default + :card? false + :container-style style/data-item + :title (i18n/label :t/max-fees) + :subtitle (i18n/label :t/no-fees)}]]]])) + diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/sign_transaction/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/sign_transaction/view.cljs new file mode 100644 index 0000000000..15f54467b2 --- /dev/null +++ b/src/status_im/contexts/wallet/wallet_connect/modals/sign_transaction/view.cljs @@ -0,0 +1,63 @@ +(ns status-im.contexts.wallet.wallet-connect.modals.sign-transaction.view + (:require [quo.core :as quo] + [react-native.core :as rn] + [react-native.safe-area :as safe-area] + [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.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn view + [] + (let [bottom (safe-area/get-bottom) + {:keys [customization-color] + :as account} (rf/sub [:wallet-connect/current-request-account-details]) + dapp (rf/sub [:wallet-connect/current-request-dapp]) + network (rf/sub [:wallet-connect/current-request-network]) + {:keys [max-fees-fiat-formatted + 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}] + [rn/view {:flex 1} + [rn/view {:style style/data-content-container} + [header/view + {:label (i18n/label :t/wallet-connect-sign-transaction-header) + :dapp dapp + :account account}] + [data-block/view]] + (when error-state + [quo/alert-banner + {:action? false + :text (i18n/label (condp = error-state + :not-enough-assets-to-pay-gas-fees + :t/not-enough-assets-to-pay-gas-fees + + :not-enough-assets + :t/not-enough-assets))}]) + [footer/view + {:warning-label (i18n/label :t/wallet-connect-sign-transaction-warning) + :slide-button-text (i18n/label :t/slide-to-sign) + :disabled? error-state} + [quo/data-item + {:status :default + :card? false + :container-style style/data-item + :title (i18n/label :t/network) + :subtitle-type :network + :network-image (:source network) + :subtitle (:full-name network)}] + [quo/data-item + {:size :small + :status :default + :card? false + :container-style style/data-item + :title (i18n/label :t/max-fees) + :subtitle (or max-fees-fiat-formatted (i18n/label :t/no-fees))}]]]])) + diff --git a/src/status_im/contexts/wallet/wallet_connect/processing_events.cljs b/src/status_im/contexts/wallet/wallet_connect/processing_events.cljs index 54fee0c108..8e4cddd04b 100644 --- a/src/status_im/contexts/wallet/wallet_connect/processing_events.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/processing_events.cljs @@ -6,31 +6,32 @@ [taoensso.timbre :as log] [utils.transforms :as transforms])) -(def ^:private method-to-screen - {constants/wallet-connect-personal-sign-method :screen/wallet-connect.sign-message - constants/wallet-connect-eth-sign-typed-method :screen/wallet-connect.sign-message - constants/wallet-connect-eth-sign-method :screen/wallet-connect.sign-message - constants/wallet-connect-eth-sign-typed-v4-method :screen/wallet-connect.sign-message}) - (rf/reg-event-fx :wallet-connect/process-session-request (fn [{:keys [db]} [event]] (let [method (wallet-connect-core/get-request-method event) - screen (method-to-screen method)] + screen (wallet-connect-core/method-to-screen method)] (if screen {:db (assoc-in db [:wallet-connect/current-request :event] event) :fx [(condp = method - constants/wallet-connect-personal-sign-method - [:dispatch [:wallet-connect/process-personal-sign]] + constants/wallet-connect-eth-send-transaction-method + [:dispatch [:wallet-connect/process-eth-send-transaction]] constants/wallet-connect-eth-sign-method [:dispatch [:wallet-connect/process-eth-sign]] + constants/wallet-connect-eth-sign-transaction-method + [:dispatch [:wallet-connect/process-eth-sign-transaction]] + constants/wallet-connect-eth-sign-typed-method [:dispatch [:wallet-connect/process-sign-typed]] constants/wallet-connect-eth-sign-typed-v4-method - [:dispatch [:wallet-connect/process-sign-typed]]) + [:dispatch [:wallet-connect/process-sign-typed]] + + constants/wallet-connect-personal-sign-method + [:dispatch [:wallet-connect/process-personal-sign]]) + [:dispatch [:open-modal screen]]]} (log/error "Didn't find screen for Wallet Connect method" {:method method @@ -60,6 +61,34 @@ :raw-data raw-data :display-data (or parsed-data raw-data))}))) +(rf/reg-event-fx + :wallet-connect/process-eth-send-transaction + (fn [{:keys [db]}] + (let [event (wallet-connect-core/get-db-current-request-event db) + display-data (-> event + clj->js + (js/JSON.stringify nil 2)) + {:keys [to]} (-> event wallet-connect-core/get-request-params first)] + {:db (update-in db + [:wallet-connect/current-request] + assoc + :address to + :raw-data event + :display-data display-data)}))) + +(rf/reg-event-fx + :wallet-connect/process-eth-sign-transaction + (fn [{:keys [db]}] + (let [event (wallet-connect-core/get-db-current-request-event db) + display-data (.stringify js/JSON (clj->js event) nil 2) + {:keys [to]} (-> event wallet-connect-core/get-request-params first)] + {:db (update-in db + [:wallet-connect/current-request] + assoc + :address to + :raw-data event + :display-data display-data)}))) + (rf/reg-event-fx :wallet-connect/process-sign-typed (fn [{:keys [db]}] diff --git a/src/status_im/contexts/wallet/wallet_connect/responding_events.cljs b/src/status_im/contexts/wallet/wallet_connect/responding_events.cljs index 6f096f5188..ee49f2e8e1 100644 --- a/src/status_im/contexts/wallet/wallet_connect/responding_events.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/responding_events.cljs @@ -13,9 +13,19 @@ constants/wallet-connect-personal-sign-method [:dispatch [:wallet-connect/respond-personal-sign password]] + constants/wallet-connect-eth-send-transaction-method + [:dispatch + [:wallet-connect/respond-build-transaction + #(rf/dispatch [:wallet-connect/respond-send-transaction-data password %])]] + constants/wallet-connect-eth-sign-method [:dispatch [:wallet-connect/respond-eth-sign password]] + constants/wallet-connect-eth-sign-transaction-method + [:dispatch + [:wallet-connect/respond-build-transaction + #(rf/dispatch [:wallet-connect/respond-sign-transaction-data password %])]] + constants/wallet-connect-eth-sign-typed-method [:dispatch [:wallet-connect/respond-sign-typed-data password :v1]] @@ -57,12 +67,50 @@ :on-error #(rf/dispatch [:wallet-connect/on-sign-error %]) :on-success #(rf/dispatch [:wallet-connect/send-response %])}]]}))) +(rf/reg-event-fx + :wallet-connect/respond-build-transaction + (fn [{:keys [db]} [on-success]] + (let [{:keys [raw-data]} (get db :wallet-connect/current-request) + chain-id (-> raw-data + (get-in [:params :chainId]) + wallet-connect-core/eip155->chain-id)] + {:fx [[:json-rpc/call + [{:method "wallet_buildTransaction" + :params [chain-id (js/JSON.stringify raw-data)] + :on-success on-success + :on-error [:wallet-connect/on-sign-error]}]]]}))) + +(rf/reg-event-fx + :wallet-connect/respond-send-transaction-data + (fn [_ [password data]] + (let [{:keys [address] + message-to-sign :messageToSign} data] + {:fx [[:effects.wallet-connect/sign-message + {:password password + :address address + :data message-to-sign + :on-error #(rf/dispatch [:wallet-connect/on-sign-error %]) + :on-success #(rf/dispatch [:wallet-connect/send-response %])}]]}))) + +(rf/reg-event-fx + :wallet-connect/respond-sign-transaction-data + (fn [_ [password data]] + (let [{:keys [address] + message-to-sign :messageToSign} data] + {:fx [[:effects.wallet-connect/sign-message + {:password password + :address address + :data message-to-sign + :on-error #(rf/dispatch [:wallet-connect/on-sign-error %]) + :on-success #(rf/dispatch [:wallet-connect/send-response %])}]]}))) + (rf/reg-event-fx :wallet-connect/on-sign-error (fn [{:keys [db]} [error]] (let [event (get-in db [:wallet-connect/current-request :event]) {:keys [raw-data address]} (get db :wallet-connect/current-request) - method (wallet-connect-core/get-request-method event)] + method (wallet-connect-core/get-request-method event) + screen (wallet-connect-core/method-to-screen method)] (log/error "Failed to sign Wallet Connect request" {:error error :address address @@ -70,7 +118,8 @@ :method method :wallet-connect-event event :event :wallet-connect/on-sign-error}) - {:fx [[:dispatch [:wallet-connect/close-session-request]]]}))) + {:fx [[:dispatch [:dismiss-modal screen]] + [:dispatch [:wallet-connect/reset-current-request]]]}))) (rf/reg-event-fx @@ -78,6 +127,7 @@ (fn [{:keys [db]} [result]] (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) web3-wallet (get db :wallet-connect/web3-wallet)] {:fx [[:effects.wallet-connect/respond-session-request {:web3-wallet web3-wallet @@ -90,7 +140,9 @@ :method method :event :wallet-connect/send-response :wallet-connect-event event}) - (rf/dispatch [:wallet-connect/close-session-request])) + (rf/dispatch [:dismiss-modal screen]) + (rf/dispatch [:wallet-connect/reset-current-request])) :on-success (fn [] (log/info "Successfully sent Wallet Connect response to dApp") - (rf/dispatch [:wallet-connect/close-session-request]))}]]}))) + (rf/dispatch [:dismiss-modal screen]) + (rf/dispatch [:wallet-connect/reset-current-request]))}]]}))) diff --git a/src/status_im/contexts/wallet/wallet_connect/sign_message/style.cljs b/src/status_im/contexts/wallet/wallet_connect/sign_message/style.cljs deleted file mode 100644 index 3484858cd7..0000000000 --- a/src/status_im/contexts/wallet/wallet_connect/sign_message/style.cljs +++ /dev/null @@ -1,29 +0,0 @@ -(ns status-im.contexts.wallet.wallet-connect.sign-message.style - (:require [quo.foundations.colors :as colors] - [status-im.constants :as constants])) - -(defn container - [bottom] - {:position :absolute - :bottom bottom - :top 0 - :left 0 - :right 0 - :padding-top constants/sheet-screen-handle-height}) - -(def content-container - {:flex 1 - :padding-horizontal 20}) - -(def fees-container - {:padding-top 12 - :padding-bottom 4 - :background-color colors/white}) - -(def auth-container - {:height 48 - :margin-vertical 12}) - -(def warning-container - {:align-items :center - :margin-bottom 12}) diff --git a/src/status_im/contexts/wallet/wallet_connect/sign_message/view.cljs b/src/status_im/contexts/wallet/wallet_connect/sign_message/view.cljs deleted file mode 100644 index 34e040ef27..0000000000 --- a/src/status_im/contexts/wallet/wallet_connect/sign_message/view.cljs +++ /dev/null @@ -1,82 +0,0 @@ -(ns status-im.contexts.wallet.wallet-connect.sign-message.view - (:require [quo.core :as quo] - [quo.foundations.colors :as colors] - [react-native.core :as rn] - [react-native.safe-area :as safe-area] - [status-im.common.raw-data-block.view :as raw-data-block] - [status-im.common.standard-authentication.core :as standard-authentication] - [status-im.contexts.wallet.wallet-connect.sign-message.style :as style] - [utils.i18n :as i18n] - [utils.re-frame :as rf])) - -(defn- close-sheet - [] - (rf/dispatch [:navigate-back])) - -(defn- on-auth-success - [password] - (rf/dispatch [:hide-bottom-sheet]) - (rf/dispatch [:wallet-connect/respond-current-session password])) - -;; NOTE: this will be a reusable component -(defn- header - [{:keys [emoji customization-color name]}] - [rn/view - {:style {:padding-vertical 12}} - [quo/text - {:size :heading-1 - :weight :semi-bold} - [rn/view {:style {:margin-top -4}} - [quo/summary-tag - {:label "dapp placeholder"}]] - (i18n/label :t/wallet-connect-sign-header) - [rn/view {:style {:padding-top 4}} - [quo/summary-tag - {:type :account - :emoji emoji - :label name - :customization-color customization-color}]]]]) - -(defn data-block - [] - (let [display-data (rf/sub [:wallet-connect/current-request-display-data])] - [raw-data-block/view {:data display-data}])) - -(defn view - [] - (let [bottom (safe-area/get-bottom) - {:keys [name emoji customization-color]} (rf/sub - [:wallet-connect/current-request-account-details])] - [rn/view {:style (style/container bottom)} - [quo/gradient-cover {:customization-color customization-color}] - [quo/page-nav - {:icon-name :i/close - :background :blur - :on-press close-sheet - :accessibility-label :wallet-connect-sign-message-close}] - [rn/view {:style style/content-container} - [header - {:emoji emoji - :customization-color customization-color - :name name}] - [data-block] - [quo/data-item - {:size :small - :status :default - :card? false - :container-style style/fees-container - :title (i18n/label :t/max-fees) - :subtitle (i18n/label :t/no-fees)}] - [rn/view {:style style/auth-container} - [standard-authentication/slide-button - {:size :size-48 - :track-text (i18n/label :t/slide-to-sign) - :customization-color customization-color - :on-auth-success on-auth-success - :auth-button-label (i18n/label :t/confirm)}]] - [rn/view {:style style/warning-container} - [quo/text - {:size :paragraph-2 - :style {:color colors/neutral-80-opa-70} - :weight :medium} - (i18n/label :t/wallet-connect-sign-warning)]]]])) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 9b83b4441d..c31cd7cbee 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -116,8 +116,12 @@ [status-im.contexts.wallet.send.transaction-confirmation.view :as wallet-transaction-confirmation] [status-im.contexts.wallet.send.transaction-progress.view :as wallet-transaction-progress] [status-im.contexts.wallet.swap.select-asset-to-pay.view :as wallet-swap-select-asset-to-pay] + [status-im.contexts.wallet.wallet-connect.modals.send-transaction.view :as + wallet-connect-send-transaction] + [status-im.contexts.wallet.wallet-connect.modals.sign-message.view :as wallet-connect-sign-message] + [status-im.contexts.wallet.wallet-connect.modals.sign-transaction.view :as + wallet-connect-sign-transaction] [status-im.contexts.wallet.wallet-connect.session-proposal.view :as wallet-connect-session-proposal] - [status-im.contexts.wallet.wallet-connect.sign-message.view :as wallet-connect-sign-message] [status-im.navigation.options :as options] [status-im.navigation.transitions :as transitions])) @@ -531,6 +535,14 @@ :options {:sheet? true} :component wallet-connect-sign-message/view} + {:name :screen/wallet-connect.sign-transaction + :options {:sheet? true} + :component wallet-connect-sign-transaction/view} + + {:name :screen/wallet-connect.send-transaction + :options {:sheet? true} + :component wallet-connect-send-transaction/view} + ;; Settings {:name :screen/settings-password diff --git a/src/status_im/subs/wallet/networks.cljs b/src/status_im/subs/wallet/networks.cljs index d8bdea7c43..1af52c3974 100644 --- a/src/status_im/subs/wallet/networks.cljs +++ b/src/status_im/subs/wallet/networks.cljs @@ -1,7 +1,5 @@ (ns status-im.subs.wallet.networks - (:require [quo.foundations.resources :as resources] - [re-frame.core :as re-frame] - [status-im.constants :as constants] + (:require [re-frame.core :as re-frame] [status-im.contexts.wallet.common.utils.networks :as network-utils])) (def max-network-prefixes 2) @@ -18,41 +16,6 @@ (fn [[networks test-networks-enabled?]] (get networks (if test-networks-enabled? :test :prod)))) -(def mainnet-network-details - {:source (resources/get-network constants/mainnet-network-name) - :short-name constants/mainnet-short-name - :network-name constants/mainnet-network-name - :abbreviated-name constants/mainnet-abbreviated-name}) - -(def arbitrum-network-details - {:source (resources/get-network constants/arbitrum-network-name) - :short-name constants/arbitrum-short-name - :network-name constants/arbitrum-network-name - :abbreviated-name constants/arbitrum-abbreviated-name}) - -(def optimism-network-details - {:source (resources/get-network constants/optimism-network-name) - :short-name constants/optimism-short-name - :network-name constants/optimism-network-name - :abbreviated-name constants/optimism-abbreviated-name}) - -(defn get-network-details - [chain-id] - (condp contains? chain-id - #{constants/ethereum-mainnet-chain-id constants/ethereum-goerli-chain-id - constants/ethereum-sepolia-chain-id} - mainnet-network-details - - #{constants/arbitrum-mainnet-chain-id constants/arbitrum-goerli-chain-id - constants/arbitrum-sepolia-chain-id} - arbitrum-network-details - - #{constants/optimism-mainnet-chain-id constants/optimism-goerli-chain-id - constants/optimism-sepolia-chain-id} - optimism-network-details - - nil)) - (re-frame/reg-sub :wallet/network-details :<- [:wallet/networks-by-mode] @@ -60,7 +23,7 @@ (->> networks (map (fn [{:keys [chain-id related-chain-id layer]}] - (assoc (get-network-details chain-id) + (assoc (network-utils/get-network-details chain-id) :chain-id chain-id :related-chain-id related-chain-id :layer layer))) diff --git a/src/status_im/subs/wallet/networks_test.cljs b/src/status_im/subs/wallet/networks_test.cljs index 15d49dc5f8..65fc7fdb4f 100644 --- a/src/status_im/subs/wallet/networks_test.cljs +++ b/src/status_im/subs/wallet/networks_test.cljs @@ -12,6 +12,7 @@ :short-name "eth" :network-name :mainnet :abbreviated-name "Eth." + :full-name "Mainnet" :related-chain-id 1 :chain-id 3 :layer 1} @@ -47,15 +48,18 @@ :short-name "eth" :chain-id 1 :abbreviated-name "Eth." + :full-name "Mainnet" :layer 1} {:network-name :arbitrum :short-name "arb1" :abbreviated-name "Arb1." + :full-name "Arbitrum" :chain-id 42161 :layer 2} {:network-name :optimism :short-name "oeth" :abbreviated-name "Oeth." + :full-name "Optimism" :chain-id 10 :layer 2}] (map #(dissoc % :source :related-chain-id) (rf/sub [sub-name])))))) @@ -70,15 +74,18 @@ :short-name "eth" :chain-id 1 :abbreviated-name "Eth." + :full-name "Mainnet" :layer 1} :arbitrum {:network-name :arbitrum :short-name "arb1" :abbreviated-name "Arb1." + :full-name "Arbitrum" :chain-id 42161 :layer 2} :optimism {:network-name :optimism :short-name "oeth" :abbreviated-name "Oeth." + :full-name "Optimism" :chain-id 10 :layer 2}} (rf/sub [sub-name]))))) diff --git a/src/status_im/subs/wallet/wallet_connect.cljs b/src/status_im/subs/wallet/wallet_connect.cljs index d523d144b0..a7609c5b84 100644 --- a/src/status_im/subs/wallet/wallet_connect.cljs +++ b/src/status_im/subs/wallet/wallet_connect.cljs @@ -1,6 +1,9 @@ (ns status-im.subs.wallet.wallet-connect (:require [re-frame.core :as rf] - [status-im.contexts.wallet.common.utils :as wallet-utils])) + [status-im.contexts.wallet.common.utils :as wallet-utils] + [status-im.contexts.wallet.common.utils.networks :as networks] + [status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core] + [utils.money :as money])) (rf/reg-sub :wallet-connect/current-request-address @@ -31,6 +34,79 @@ :name name :emoji emoji}))) +(rf/reg-sub + :wallet-connect/current-request-dapp + :<- [:wallet-connect/current-request] + :<- [:wallet-connect/pairings] + (fn [[request pairings]] + (let [dapp-url (get-in request [:raw-data :verifyContext :verified :origin])] + (->> pairings + (filter (fn [pairing] + (= dapp-url (get-in pairing [:peerMetadata :url])))) + (first))))) + +(rf/reg-sub + :wallet-connect/current-request-network + :<- [:wallet-connect/current-request] + (fn [request] + (-> request + (get-in [:raw-data :params :chainId]) + (wallet-connect-core/eip155->chain-id) + (networks/get-network-details)))) + +(rf/reg-sub + :wallet-connect/current-request-transaction-information + :<- [:wallet-connect/current-request] + :<- [:wallet/accounts] + :<- [:profile/currency] + :<- [:profile/currency-symbol] + (fn [[request accounts currency currency-symbol]] + (let [chain-id (-> request + (get-in [:raw-data :params :chainId]) + (wallet-connect-core/eip155->chain-id)) + all-tokens (->> accounts + (filter #(= (:address %) + (:address request))) + (first) + :tokens) + eth-token (->> all-tokens + (filter #(= (:symbol %) "ETH")) + (first)) + {:keys [gasPrice gasLimit value]} (-> request + :raw-data + wallet-connect-core/get-request-params + first) + max-fees-wei (money/bignumber (* gasPrice gasLimit))] + (when (and gasPrice gasLimit) + (let [max-fees-ether (money/wei->ether max-fees-wei) + token-fiat-value (wallet-utils/calculate-token-fiat-value {:currency currency + :balance max-fees-ether + :token eth-token}) + crypto-formatted (wallet-utils/get-standard-crypto-format eth-token max-fees-ether) + fiat-formatted (wallet-utils/get-standard-fiat-format crypto-formatted + currency-symbol + token-fiat-value) + balance (-> eth-token + (get-in [:balances-per-chain chain-id :raw-balance]) + (money/bignumber)) + value (money/bignumber value) + total-transaction-value (money/add max-fees-wei value)] + {:total-transaction-value total-transaction-value + :balance balance + :max-fees max-fees-wei + :max-fees-fiat-value token-fiat-value + :max-fees-fiat-formatted fiat-formatted + :error-state (cond + (and + (money/sufficient-funds? value balance) + (not (money/sufficient-funds? total-transaction-value balance))) + :not-enough-assets-to-pay-gas-fees + + (not (money/sufficient-funds? value balance)) + :not-enough-assets + + :else nil)}))))) + (rf/reg-sub :wallet-connect/session-proposer :<- [:wallet-connect/current-proposal] diff --git a/src/status_im/subs/wallet/wallet_test.cljs b/src/status_im/subs/wallet/wallet_test.cljs index 546cf798c6..2fe56bda7f 100644 --- a/src/status_im/subs/wallet/wallet_test.cljs +++ b/src/status_im/subs/wallet/wallet_test.cljs @@ -526,18 +526,21 @@ (match? [{:short-name "eth" :network-name :mainnet :abbreviated-name "Eth." + :full-name "Mainnet" :chain-id 1 :related-chain-id nil :layer 1} {:short-name "arb1" :network-name :arbitrum :abbreviated-name "Arb1." + :full-name "Arbitrum" :chain-id 42161 :related-chain-id nil :layer 2} {:short-name "oeth" :network-name :optimism :abbreviated-name "Oeth." + :full-name "Optimism" :chain-id 10 :related-chain-id nil :layer 2}] diff --git a/translations/en.json b/translations/en.json index 143f3a7d0e..78a9859a5b 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1930,6 +1930,8 @@ "pinned-by": "Pinned by", "pin-limit-reached": "Pin limit reached. Unpin a previous message first.", "no-fees": "No fees", + "not-enough-assets-to-pay-gas-fees": "Not enough assets to pay gas fees.", + "not-enough-assets": "Not enough assets to complete transaction.", "max-fee": "Max fee", "max-fees": "Max fees", "max-priority-fee": "Max priority fee", @@ -2029,8 +2031,12 @@ "wallet-connect-go-back": "Go back to your browser or dapp", "wallet-connect-2.0": "Wallet Connect 2.0", "wallet-connect": "Wallet Connect", - "wallet-connect-sign-header": "wants you to sign a message with", - "wallet-connect-sign-warning": "Sign messages only if you trust the dApp", + "wallet-connect-sign-message-header": "wants you to sign the message with", + "wallet-connect-send-transaction-header": "wants you to send this transaction with", + "wallet-connect-sign-transaction-header": "wants you to sign this transaction with", + "wallet-connect-sign-message-warning": "Sign messages only if you trust the dApp", + "wallet-connect-send-transaction-warning": "Send transactions only if you trust the dApp", + "wallet-connect-sign-transaction-warning": "Sign transactions only if you trust the dApp", "reject": "Reject", "manage-connections": "Manage connections from within Application Connections", "contact-request-was-ignored": "Contact request ignored", From 4bd7abaaced756fb885df0dc58b0e2107e8379f8 Mon Sep 17 00:00:00 2001 From: Volodymyr Kozieiev Date: Wed, 26 Jun 2024 14:02:55 +0100 Subject: [PATCH 08/10] Added tests for wallet send events (#20547) --- .../contexts/wallet/send/events.cljs | 31 ++-- .../contexts/wallet/send/events_test.cljs | 165 ++++++++++++++++++ 2 files changed, 181 insertions(+), 15 deletions(-) create mode 100644 src/status_im/contexts/wallet/send/events_test.cljs diff --git a/src/status_im/contexts/wallet/send/events.cljs b/src/status_im/contexts/wallet/send/events.cljs index 6f2e52b87c..98f3a9c6e2 100644 --- a/src/status_im/contexts/wallet/send/events.cljs +++ b/src/status_im/contexts/wallet/send/events.cljs @@ -205,21 +205,22 @@ token-networks-ids (mapv #(:chain-id %) token-networks) token-not-supported-in-receiver-networks? (not-any? (set receiver-networks) token-networks-ids)] - {:db (cond-> db - :always (update-in [:wallet :ui :send] dissoc :collectible) - :always (assoc-in [:wallet :ui :send :token-display-name] - (:symbol token)) - :always (assoc-in - [:wallet :ui :send :token-not-supported-in-receiver-networks?] - token-not-supported-in-receiver-networks?) - token (assoc-in [:wallet :ui :send :token] token) - token-symbol (assoc-in [:wallet :ui :send :token-symbol] token-symbol)) - :fx [[:dispatch [:wallet/clean-suggested-routes]] - [:dispatch - [:wallet/wizard-navigate-forward - {:current-screen stack-id - :start-flow? start-flow? - :flow-id :wallet-send-flow}]]]}))) + (when (or token token-symbol) + {:db (cond-> db + :always (update-in [:wallet :ui :send] dissoc :collectible) + :always (assoc-in + [:wallet :ui :send :token-not-supported-in-receiver-networks?] + token-not-supported-in-receiver-networks?) + token (assoc-in [:wallet :ui :send :token] token) + token (assoc-in [:wallet :ui :send :token-display-name] + (:symbol token)) + token-symbol (assoc-in [:wallet :ui :send :token-symbol] token-symbol)) + :fx [[:dispatch [:wallet/clean-suggested-routes]] + [:dispatch + [:wallet/wizard-navigate-forward + {:current-screen stack-id + :start-flow? start-flow? + :flow-id :wallet-send-flow}]]]})))) (rf/reg-event-fx :wallet/edit-token-to-send diff --git a/src/status_im/contexts/wallet/send/events_test.cljs b/src/status_im/contexts/wallet/send/events_test.cljs new file mode 100644 index 0000000000..a8cb0f1ef6 --- /dev/null +++ b/src/status_im/contexts/wallet/send/events_test.cljs @@ -0,0 +1,165 @@ +(ns status-im.contexts.wallet.send.events-test + (:require + [cljs.test :refer-macros [is testing]] + [re-frame.db :as rf-db] + status-im.contexts.wallet.send.events + [test-helpers.unit :as h])) + +(h/deftest-event :wallet/update-receiver-networks + [event-id dispatch] + (testing "reciever networks changed" + (let [selected-networks-before [:ethereum :optimism :arbitrum] + selected-networks-after [:ethereum :optimism] + expected-db {:wallet {:ui {:send {:receiver-networks selected-networks-after}}}}] + (reset! rf-db/app-db {:wallet {:ui {:send {:receiver-networks selected-networks-before}}}}) + (is (match? expected-db (:db (dispatch [event-id selected-networks-after])))))) + + (testing "if receiver network removed, it is also removed from disabled ones" + (let [selected-networks-before [:ethereum :optimism :arbitrum] + selected-networks-after [:ethereum :optimism] + disabled-from-chain-ids-before [:optimism :arbitrum] + disabled-from-chain-ids-after [:optimism] + expected-db {:wallet {:ui {:send {:receiver-networks selected-networks-after + :disabled-from-chain-ids + disabled-from-chain-ids-after}}}}] + (reset! rf-db/app-db {:wallet {:ui {:send {:receiver-networks selected-networks-before + :disabled-from-chain-ids + disabled-from-chain-ids-before}}}}) + (is (match? expected-db (:db (dispatch [event-id selected-networks-after]))))))) + +(h/deftest-event :wallet/set-token-to-send + [event-id dispatch] + (let [token-symbol "ETH" + token {:symbol "ETH" + :name "Ether" + :networks #{{:chain-id 421614} + {:chain-id 11155420} + {:chain-id 11155111}}} + receiver-networks [421614 11155420]] + (testing "can be called with :token" + (let [initial-db {:wallet {:ui {:send {:receiver-networks receiver-networks}}}} + expected-db {:wallet {:ui {:send {:token-display-name token-symbol + :token-not-supported-in-receiver-networks? false}}}} + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id {:token token}])] + (is (match? expected-db (:db result))))) + (testing "can be called with :token-symbol" + (testing "can be called with :token" + (let [initial-db {:wallet {:ui {:send {:receiver-networks receiver-networks}}}} + expected-db {:wallet {:ui {:send {:token-symbol token-symbol + :token-not-supported-in-receiver-networks? true}}}} + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id {:token-symbol token-symbol}])] + (is (match? expected-db (:db result)))))) + (testing "shouldn't have changes if called without :token or :token-symbol") + (let [initial-db {:wallet {:ui {:send {:receiver-networks receiver-networks}}}} + expected-db nil + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id {}])] + (is (match? expected-db (:db result)))) + (testing "should clean :collectible set" + (let [initial-db {:wallet {:ui {:send {:receiver-networks receiver-networks + :collectible "some-collectible"}}}} + expected-db {:wallet {:ui {:send {:token-display-name token-symbol + :token-not-supported-in-receiver-networks? false}}}} + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id {:token token}])] + (is (match? expected-db (:db result))) + (is (match? nil (get-in result [:db :wallet :ui :send :collectible]))))) + (testing "should set :token-not-supported-in-receiver-networks?" + (let [initial-db {:wallet {:ui {:send {:receiver-networks []}}}} + expected-db {:wallet {:ui {:send {:token-display-name token-symbol + :token-not-supported-in-receiver-networks? true}}}} + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id {:token token}])] + (is (match? expected-db (:db result))))))) + +(h/deftest-event :wallet/edit-token-to-send + [event-id dispatch] + (let [token-symbol "ETH" + token {:symbol "ETH" + :name "Ether" + :networks #{{:chain-id 421614} + {:chain-id 11155420} + {:chain-id 11155111}}} + receiver-networks [421614 11155420]] + (testing "can be called with :token" + (let [initial-db {:wallet {:ui {:send {:receiver-networks receiver-networks + :token-display-name "DAI" + :token-not-supported-in-receiver-networks? true}}}} + expected-db {:wallet {:ui {:send {:token-display-name token-symbol + :token-not-supported-in-receiver-networks? false}}}} + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id token])] + (is (match? expected-db (:db result))))) + (testing "should set :token-not-supported-in-receiver-networks?" + (let [initial-db {:wallet {:ui {:send {:receiver-networks [] + :token-display-name "DAI" + :token-not-supported-in-receiver-networks? false}}}} + expected-db {:wallet {:ui {:send {:token-display-name token-symbol + :token-not-supported-in-receiver-networks? true}}}} + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id token])] + (is (match? expected-db (:db result))))))) + +(h/deftest-event :wallet/set-collectible-to-send + [event-id dispatch] + (let + [collectible + {:data-type 2 + :id + {:contract-id + {:chain-id 11155111 + :address "0x1ed60fedff775d500dde21a974cd4e92e0047cc8"} + :token-id "15"} + :contract-type 3 + :collectible-data + {:name "DOG #1" + :description + "dogs are cute and this one is the cutestdogs are cute and this one is the cutest"} + :collection-data + {:name "ERC-1155 Faucet"} + :ownership + [{:address "0xf90014b2027e584fc96e6f6c8078998fe46c5ccb" + :balance "1" + :tx-timestamp 1710331776}] + :preview-url + {:uri + "https://ipfs.io/ipfs/bafybeie7b7g7iibpac4k6ydw4m5ivgqw5vov7oyzlf4v5zoor57wokmsxy/isolated-happy-smiling-dog-white-background-portrait-4_1562-693.avif"}} + initial-db {:wallet {:ui {:send {:token {:symbol "ETH"}}}}} + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id {:collectible collectible}])] + (testing ":collectible field assigned" + (is (match? collectible (get-in result [:db :wallet :ui :send :collectible])))) + (testing ":token should be removed" + (is (match? nil (get-in result [:db :wallet :ui :send :token])))) + (testing ":token-display-name assigned" + (is (match? "DOG #1" (get-in result [:db :wallet :ui :send :token-display-name])))) + (testing ":tx-type assigned" + (is (match? :tx/collectible-erc-1155 (get-in result [:db :wallet :ui :send :tx-type])))) + (testing "amount set if collectible was single" + (is (match? 1 (get-in result [:db :wallet :ui :send :amount])))))) + +(h/deftest-event :wallet/set-collectible-amount-to-send + [event-id dispatch] + (let [initial-db {:wallet {:ui {:send nil}}} + expected-fx [[:dispatch [:wallet/get-suggested-routes {:amount 10}]] + [:dispatch + [:wallet/wizard-navigate-forward + {:current-screen nil :flow-id :wallet-send-flow}]]] + amount 10 + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id {:amount amount}])] + (testing "amount set" + (is (match? amount (get-in result [:db :wallet :ui :send :amount])))) + (testing "effects match" + (is (match? expected-fx (:fx result)))))) + +(h/deftest-event :wallet/set-token-amount-to-send + [event-id dispatch] + (let [initial-db {:wallet {:ui {:send {:token {:symbol "ETH"}}}}} + amount 10 + _ (reset! rf-db/app-db initial-db) + result (dispatch [event-id {:amount amount}])] + (testing "amount set" + (is (match? amount (get-in result [:db :wallet :ui :send :amount])))))) From b005eb818105c851205c77366a54d47cc8e36e5e Mon Sep 17 00:00:00 2001 From: Mohsen Date: Wed, 26 Jun 2024 16:44:29 +0330 Subject: [PATCH 09/10] feat!: add saved addresses to wallet settings (#20475) --- .../components/selectors/selectors/style.cljs | 2 +- src/quo/components/share/qr_code/style.cljs | 6 +++ src/quo/components/share/qr_code/view.cljs | 7 +-- .../add_address_to_save/style.cljs | 3 +- .../add_address_to_save/view.cljs | 6 +-- .../saved_addresses/save_address/view.cljs | 9 ++-- .../settings/wallet/saved_addresses/view.cljs | 43 +++++++++++-------- .../settings/wallet/wallet_options/view.cljs | 10 ++--- .../wallet/common/scan_account/view.cljs | 2 +- .../contexts/wallet/common/utils.cljs | 3 +- .../sheets/network_preferences/view.cljs | 7 ++- src/status_im/feature_flags.cljs | 2 - .../subs/wallet/saved_addresses.cljs | 4 +- translations/en.json | 3 +- 14 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/quo/components/selectors/selectors/style.cljs b/src/quo/components/selectors/selectors/style.cljs index c945f567e2..417591f756 100644 --- a/src/quo/components/selectors/selectors/style.cljs +++ b/src/quo/components/selectors/selectors/style.cljs @@ -31,7 +31,7 @@ (defn- checkbox-border-unchecked-color [theme] {:normal (colors/theme-colors colors/neutral-30 colors/neutral-70 theme) - :blur (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-40 theme)}) + :blur (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)}) (defn- filled-checkbox-background-color [theme] diff --git a/src/quo/components/share/qr_code/style.cljs b/src/quo/components/share/qr_code/style.cljs index ab72ad46af..3fdee84e04 100644 --- a/src/quo/components/share/qr_code/style.cljs +++ b/src/quo/components/share/qr_code/style.cljs @@ -39,6 +39,12 @@ (def avatar-container-rounded (assoc avatar-container-common :border-radius 16)) +(def big-avatar-container-rounded + (assoc avatar-container-common + :width 84 + :height 84 + :border-radius 42)) + (def community-logo-image {:width 64 :height 64 diff --git a/src/quo/components/share/qr_code/view.cljs b/src/quo/components/share/qr_code/view.cljs index 2ed627db04..4ff539cb6b 100644 --- a/src/quo/components/share/qr_code/view.cljs +++ b/src/quo/components/share/qr_code/view.cljs @@ -13,8 +13,9 @@ :as props}] [rn/view {:style style/avatar-overlay} [rn/view - {:style (if (= avatar-type :wallet-account) - style/avatar-container-rounded + {:style (case avatar-type + :wallet-account style/avatar-container-rounded + :saved-address style/big-avatar-container-rounded style/avatar-container-circular)} (case avatar-type :profile @@ -37,7 +38,7 @@ [channel-avatar/view (assoc props :locked? nil :size :size-64)] :saved-address - [wallet-avatar/wallet-user-avatar (assoc props :size :size-64)] + [wallet-avatar/wallet-user-avatar (assoc props :size :size-80)] nil)]]) diff --git a/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/style.cljs b/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/style.cljs index 3b44e5217a..8e8b8b5d8b 100644 --- a/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/style.cljs +++ b/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/style.cljs @@ -27,4 +27,5 @@ {:color colors/white-opa-40}) (def saved-address-item - {:margin-top 4}) + {:margin-top 4 + :background-color colors/white-opa-5}) diff --git a/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/view.cljs b/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/view.cljs index 1d081d0e44..7dae092de6 100644 --- a/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/view.cljs +++ b/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/view.cljs @@ -49,6 +49,7 @@ :multiline? true :on-clear clear-input :return-key-type :done + :auto-focus true :clearable? (not empty-input?) :on-change-text on-change-text :button (when empty-input? @@ -83,7 +84,7 @@ [quo/info-message {:accessibility-label :error-message :size :default - :icon :i/info + :icon :i/alert :type :error :style style/info-message} error-msg]))) @@ -91,8 +92,7 @@ (defn- existing-saved-address [{:keys [address]}] (let [{:keys [name customization-color chain-short-names ens ens?]} - (rf/sub [:wallet/saved-address-by-address - address])] + (rf/sub [:wallet/saved-address-by-address address])] [rn/view {:style style/existing-saved-address-container} [quo/text {:size :paragraph-1 diff --git a/src/status_im/contexts/settings/wallet/saved_addresses/save_address/view.cljs b/src/status_im/contexts/settings/wallet/saved_addresses/save_address/view.cljs index 8271573606..57372f7386 100644 --- a/src/status_im/contexts/settings/wallet/saved_addresses/save_address/view.cljs +++ b/src/status_im/contexts/settings/wallet/saved_addresses/save_address/view.cljs @@ -93,20 +93,19 @@ :subtitle-type :default :label :none :blur? true - :icon-right? (not ens?) - :right-icon :i/advanced + :right-icon (when-not ens? :i/advanced) :card? true :title (i18n/label :t/address) :subtitle ens :custom-subtitle address-text - :on-press open-network-preferences + :on-press (when-not ens? open-network-preferences) :container-style style/data-item} ens? (dissoc :custom-subtitle)) [ens ens? open-network-preferences address-text])] [quo/overlay {:type :shell} [floating-button-page/view - {:footer-container-padding 0 + {:footer-container-padding (if edit? (+ (safe-area/get-bottom) 12) 0) :header [quo/page-nav {:type :no-title :background :blur @@ -133,7 +132,7 @@ :container-style style/avatar}] [quo/title-input {:blur? true - :auto-focus true + :auto-focus (not edit?) :max-length 24 :size :heading-1 :placeholder placeholder diff --git a/src/status_im/contexts/settings/wallet/saved_addresses/view.cljs b/src/status_im/contexts/settings/wallet/saved_addresses/view.cljs index f55466e81b..48bfe88aca 100644 --- a/src/status_im/contexts/settings/wallet/saved_addresses/view.cljs +++ b/src/status_im/contexts/settings/wallet/saved_addresses/view.cljs @@ -73,27 +73,34 @@ (defn- filtered-list [{:keys [search-text]}] - [rn/flat-list - {:key-fn :address - :data (rf/sub [:wallet/filtered-saved-addresses search-text]) - :render-fn saved-address - :shows-vertical-scroll-indicator false - :keyboard-should-persist-taps :always - :content-container-style {:flex-grow 1} - :empty-component [empty-result]}]) + (let [search-result (rf/sub [:wallet/filtered-saved-addresses search-text])] + (if (empty? search-result) + [empty-result] + [rn/flat-list + {:key-fn :address + :data search-result + :render-fn saved-address + :shows-vertical-scroll-indicator false + :keyboard-should-persist-taps :always + :content-container-style {:flex-grow 1} + :bounces false + :over-scroll-mode :never}]))) (defn- unfiltered-list [{:keys [grouped-saved-addresses]}] - [rn/section-list - {:key-fn :title - :shows-vertical-scroll-indicator false - :sticky-section-headers-enabled false - :keyboard-should-persist-taps :always - :render-section-header-fn header - :sections grouped-saved-addresses - :render-fn saved-address - :content-container-style {:flex-grow 1} - :empty-component [empty-list]}]) + (if (empty? grouped-saved-addresses) + [empty-list] + [rn/section-list + {:key-fn :title + :shows-vertical-scroll-indicator false + :sticky-section-headers-enabled false + :keyboard-should-persist-taps :always + :render-section-header-fn header + :sections grouped-saved-addresses + :render-fn saved-address + :bounces false + :over-scroll-mode :never + :content-container-style {:flex-grow 1}}])) (defn- navigate-back [] diff --git a/src/status_im/contexts/settings/wallet/wallet_options/view.cljs b/src/status_im/contexts/settings/wallet/wallet_options/view.cljs index 58153e98c5..b1b4f9daa0 100644 --- a/src/status_im/contexts/settings/wallet/wallet_options/view.cljs +++ b/src/status_im/contexts/settings/wallet/wallet_options/view.cljs @@ -2,7 +2,6 @@ (:require [quo.core :as quo] [react-native.safe-area :as safe-area] [status-im.contexts.settings.wallet.wallet-options.style :as style] - [status-im.feature-flags :as ff] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -20,11 +19,10 @@ :blur? true :on-press open-keypairs-and-accounts-settings-modal :action :arrow} - (when (ff/enabled? ::ff/settings.saved-addresses) - {:title (i18n/label :t/saved-addresses) - :blur? true - :on-press open-saved-addresses-settings-modal - :action :arrow})]) + {:title (i18n/label :t/saved-addresses) + :blur? true + :on-press open-saved-addresses-settings-modal + :action :arrow}]) (defn basic-settings [] diff --git a/src/status_im/contexts/wallet/common/scan_account/view.cljs b/src/status_im/contexts/wallet/common/scan_account/view.cljs index 6a35b53b80..966c6d0ade 100644 --- a/src/status_im/contexts/wallet/common/scan_account/view.cljs +++ b/src/status_im/contexts/wallet/common/scan_account/view.cljs @@ -28,7 +28,7 @@ (let [{:keys [on-result]} (rf/sub [:get-screen-params])] [scan-qr-code/view {:title (i18n/label :t/scan-qr) - :subtitle (i18n/label :t/scan-an-account-qr-code) + :subtitle (i18n/label :t/scan-an-address-qr-code) :error-message (i18n/label :t/oops-this-qr-does-not-contain-an-address) :validate-fn #(contains-supported-address? %) :on-success-scan (fn [result] diff --git a/src/status_im/contexts/wallet/common/utils.cljs b/src/status_im/contexts/wallet/common/utils.cljs index e26e606eae..b0f7f6ec7a 100644 --- a/src/status_im/contexts/wallet/common/utils.cljs +++ b/src/status_im/contexts/wallet/common/utils.cljs @@ -220,7 +220,7 @@ (defn make-network-item "This function generates props for quo/category component item" - [{:keys [network-name color on-change networks state label-props type]}] + [{:keys [network-name color on-change networks state label-props type blur?]}] (cond-> {:title (string/capitalize (name network-name)) :image :icon-avatar :image-props {:icon (resources/get-network network-name) @@ -230,6 +230,7 @@ (if (= :default state) :filled-checkbox :checkbox)) + :blur? blur? :customization-color color :checked? (contains? networks network-name) :on-change on-change}} diff --git a/src/status_im/contexts/wallet/sheets/network_preferences/view.cljs b/src/status_im/contexts/wallet/sheets/network_preferences/view.cljs index e47c964c13..f460067123 100644 --- a/src/status_im/contexts/wallet/sheets/network_preferences/view.cljs +++ b/src/status_im/contexts/wallet/sheets/network_preferences/view.cljs @@ -90,10 +90,7 @@ :address address :blur? blur? :format :long}]) - :container-style (merge style/data-item - {:background-color (colors/theme-colors colors/neutral-2_5 - colors/neutral-90 - theme)})}]) + :container-style style/data-item}]) [quo/category {:list-type :settings :blur? blur? @@ -106,6 +103,7 @@ :normal-checkbox? receiver? :networks (get-current-preferences-names) :type :checkbox + :blur? blur? :on-change (fn [] (toggle-network (:network-name network)) @@ -137,6 +135,7 @@ :normal-checkbox? receiver? :networks (get-current-preferences-names) :type :checkbox + :blur? blur? :on-change (fn [] (toggle-network (:network-name network)) diff --git a/src/status_im/feature_flags.cljs b/src/status_im/feature_flags.cljs index cd83ce2398..f748d17e3b 100644 --- a/src/status_im/feature_flags.cljs +++ b/src/status_im/feature_flags.cljs @@ -11,8 +11,6 @@ (def ^:private initial-flags {::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED) - ::settings.saved-addresses (enabled-in-env? - :FLAG_WALLET_SETTINGS_SAVED_ADDRESSES_ENABLED) ::settings.import-all-keypairs (enabled-in-env? :FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS) ::shell.jump-to (enabled-in-env? :ENABLE_JUMP_TO) diff --git a/src/status_im/subs/wallet/saved_addresses.cljs b/src/status_im/subs/wallet/saved_addresses.cljs index b4e977557a..8490adcc99 100644 --- a/src/status_im/subs/wallet/saved_addresses.cljs +++ b/src/status_im/subs/wallet/saved_addresses.cljs @@ -54,7 +54,7 @@ :wallet/saved-address-by-address :<- [:wallet/saved-addresses-by-network-mode] (fn [saved-addresses [_ address]] - (get saved-addresses address))) + (get saved-addresses (string/lower-case address)))) (rf/reg-sub :wallet/filtered-saved-addresses @@ -65,7 +65,7 @@ (sort-by :name) (filter (fn [{:keys [name address ens chain-short-names]}] - (let [lowercase-query (string/lower-case query)] + (let [lowercase-query (string/lower-case (string/trim query))] (or (string/includes? (string/lower-case name) lowercase-query) (string/includes? address lowercase-query) diff --git a/translations/en.json b/translations/en.json index 78a9859a5b..c3702cf6ac 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2475,7 +2475,7 @@ "make-one-it-is-easy-we-promise": "Make one, it’s easy, we promise!", "saved-addresses": "Saved addresses", "no-saved-addresses": "No saved addresses", - "you-like-to-type-43-characters": "You like to type 43 characters?", + "you-like-to-type-43-characters": "Do you like to type 43 characters?", "no-other-accounts": "No other accounts", "here-is-a-cat-in-a-box-instead": "Here’s a cat in a box instead", "accounts-count": "{{count}} accounts", @@ -2506,6 +2506,7 @@ "select-another-account": "Select another account", "oops-this-qr-does-not-contain-an-address": "Oops! This QR does not contain an address", "scan-an-account-qr-code": "Scan an account QR code", + "scan-an-address-qr-code": "Scan an address QR code", "buy-assets": "Buy assets", "one-time": "One time", "recurrent": "Recurrent", From 3ce6a86e9b9dba53c25265c243183d6884bb5aca Mon Sep 17 00:00:00 2001 From: Ulises Manuel <90291778+ulisesmac@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:10:16 -0600 Subject: [PATCH 10/10] fix(wallet): Account derivation for added keypairs (#20536) * Fix color of non-selected keypairs * Fix pressable area in keypairs * Make validation more robust * Make confirm button always pressable * Fix wrong sentence in errors * Solve account creation by fixing a memoized callback * Improve logging --- .../components/buttons/slide_button/view.cljs | 22 +++++------ src/quo/components/wallet/keypair/style.cljs | 16 ++++---- src/quo/components/wallet/keypair/view.cljs | 37 ++++++++++--------- .../add_account/create_account/events.cljs | 15 ++++---- .../create_account/select_keypair/view.cljs | 3 +- .../add_account/create_account/view.cljs | 4 +- src/status_im/contexts/wallet/events.cljs | 7 ++-- 7 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/quo/components/buttons/slide_button/view.cljs b/src/quo/components/buttons/slide_button/view.cljs index dc9504f5e4..9a8d9bbbb1 100644 --- a/src/quo/components/buttons/slide_button/view.cljs +++ b/src/quo/components/buttons/slide_button/view.cljs @@ -14,9 +14,7 @@ [react-native.reanimated :as reanimated])) (defn drag-gesture - [x-pos disabled? track-width sliding-complete? - set-sliding-complete - on-complete reset-fn] + [x-pos disabled? track-width sliding-complete? set-sliding-complete on-complete reset-fn] (-> (gesture/gesture-pan) (gesture/with-test-ID :slide-button-gestures) (gesture/enabled (not disabled?)) @@ -71,14 +69,16 @@ (dimensions :thumb)) [dimensions]) custom-color (if (= type :danger) :danger customization-color) - gesture (rn/use-memo #(drag-gesture x-pos - disabled? - (dimensions :usable-track) - sliding-complete? - set-sliding-complete - on-complete - reset-fn) - [sliding-complete? disabled?])] + gesture (rn/use-memo + (fn [] + (drag-gesture x-pos + disabled? + (dimensions :usable-track) + sliding-complete? + set-sliding-complete + on-complete + reset-fn)) + [sliding-complete? disabled? on-complete])] [gesture/gesture-detector {:gesture gesture} [reanimated/view diff --git a/src/quo/components/wallet/keypair/style.cljs b/src/quo/components/wallet/keypair/style.cljs index d56e49882c..ebd6379147 100644 --- a/src/quo/components/wallet/keypair/style.cljs +++ b/src/quo/components/wallet/keypair/style.cljs @@ -7,14 +7,14 @@ [{:keys [blur? customization-color theme selected? container-style]}] (merge {:border-radius 16 :border-width 1 - :border-color (if selected? - (if blur? - colors/white - (colors/resolve-color customization-color theme)) - (if blur? - colors/white-opa-5 - (colors/theme-colors colors/neutral-10 colors/neutral-80 theme))) - :padding-bottom 8} + :padding-bottom 8 + :border-color (cond + (and selected? blur?) colors/white + selected? (colors/resolve-color customization-color theme) + blur? colors/white-opa-5 + :else (colors/theme-colors colors/neutral-10 + colors/neutral-80 + theme))} container-style)) (def header-container diff --git a/src/quo/components/wallet/keypair/view.cljs b/src/quo/components/wallet/keypair/view.cljs index d6ab053cf1..72f5ec937f 100644 --- a/src/quo/components/wallet/keypair/view.cljs +++ b/src/quo/components/wallet/keypair/view.cljs @@ -95,20 +95,23 @@ (defn view [{:keys [accounts action container-style selected? on-press] :as props}] - [rn/pressable - {:style (style/container (merge props - {:selected? selected? - :container-style container-style})) - :on-press #(when (= action :selector) (on-press))} - [rn/view {:style style/header-container} - [avatar props] - [rn/view - {:style {:margin-left 8 - :flex 1}} - [title-view (assoc props :selected? selected?)] - [details-view props]]] - [rn/flat-list - {:data accounts - :render-fn acc-list-card - :separator [rn/view {:style {:height 8}}] - :style {:padding-horizontal 8}}]]) + (let [theme (quo.theme/use-theme)] + [rn/pressable + {:style (style/container (assoc props + :selected? selected? + :container-style container-style + :theme theme)) + :on-press #(when (= action :selector) (on-press)) + :pointer-events :box-only} + [rn/view {:style style/header-container} + [avatar props] + [rn/view + {:style {:margin-left 8 + :flex 1}} + [title-view (assoc props :selected? selected?)] + [details-view props]]] + [rn/flat-list + {:data accounts + :render-fn acc-list-card + :separator [rn/view {:style {:height 8}}] + :style {:padding-horizontal 8}}]])) diff --git a/src/status_im/contexts/wallet/add_account/create_account/events.cljs b/src/status_im/contexts/wallet/add_account/create_account/events.cljs index 6680651791..dd7f56ca78 100644 --- a/src/status_im/contexts/wallet/add_account/create_account/events.cljs +++ b/src/status_im/contexts/wallet/add_account/create_account/events.cljs @@ -124,7 +124,7 @@ :on-success on-success :on-error (fn [error] (log/error - "Failed to resolve next path derivation path" + "Failed to resolve next derivation path" {:event :wallet/next-derivation-path :method "accounts_resolveSuggestedPathForKeypair" :error error @@ -191,7 +191,7 @@ (rf/reg-event-fx :wallet/derive-address-and-add-account - (fn [_ [{:keys [password derived-from-address derivation-path account-preferences]}]] + (fn [_ [{:keys [password derived-from-address derivation-path account-preferences key-uid]}]] {:fx [[:json-rpc/call [{:method "wallet_getDerivedAddresses" :params [(security/safe-unmask-data password) @@ -199,9 +199,10 @@ [derivation-path]] :on-success (fn [[derived-account]] (rf/dispatch [:wallet/add-account - (assoc account-preferences :password password) + (assoc account-preferences + :key-uid key-uid + :password password) derived-account])) - :on-error #(log/info "Failed to get derived addresses" - derived-from-address - %)}]]]})) - + :on-error [:wallet/log-rpc-error + {:event :wallet/derive-address-and-add-account + :params [derived-from-address [derivation-path]]}]}]]]})) diff --git a/src/status_im/contexts/wallet/add_account/create_account/select_keypair/view.cljs b/src/status_im/contexts/wallet/add_account/create_account/select_keypair/view.cljs index dc106ce9cf..ae225a3e92 100644 --- a/src/status_im/contexts/wallet/add_account/create_account/select_keypair/view.cljs +++ b/src/status_im/contexts/wallet/add_account/create_account/select_keypair/view.cljs @@ -105,8 +105,7 @@ [quo/bottom-actions {:actions :one-action :button-one-label (i18n/label :t/confirm-account-origin) - :button-one-props {:disabled? (= selected-keypair selected-key-uid) - :customization-color customization-color + :button-one-props {:customization-color customization-color :on-press #(rf/dispatch [:wallet/confirm-account-origin selected-key-uid])} :container-style style/bottom-action-container}]])) diff --git a/src/status_im/contexts/wallet/add_account/create_account/view.cljs b/src/status_im/contexts/wallet/add_account/create_account/view.cljs index 9693f192f9..8e4099fab2 100644 --- a/src/status_im/contexts/wallet/add_account/create_account/view.cljs +++ b/src/status_im/contexts/wallet/add_account/create_account/view.cljs @@ -48,7 +48,6 @@ :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} @@ -217,6 +216,7 @@ [:wallet/derive-address-and-add-account {:password password :derived-from-address derived-from + :key-uid key-uid :derivation-path @derivation-path :account-preferences preferences}]))) [derived-from])] @@ -231,7 +231,7 @@ {:account-color @account-color :slide-button-props {:on-auth-success on-auth-success :disabled? (or (empty? @account-name) - (= "" @derivation-path) + (string/blank? @derivation-path) (some? error))}} [avatar {:account-color @account-color diff --git a/src/status_im/contexts/wallet/events.cljs b/src/status_im/contexts/wallet/events.cljs index 5b751cf6d2..8eb78a1f81 100644 --- a/src/status_im/contexts/wallet/events.cljs +++ b/src/status_im/contexts/wallet/events.cljs @@ -215,13 +215,12 @@ [:dispatch [:wallet/clear-create-account]]]})) (rf/reg-event-fx :wallet/add-account - (fn [{:keys [db]} - [{:keys [password account-name emoji color type] + (fn [_ + [{:keys [key-uid password account-name emoji color type] :or {type :generated}} {:keys [public-key address path] :as _derived-account}]] (let [lowercase-address (some-> address - (string/lower-case)) - key-uid (get-in db [:wallet :ui :create-account :selected-keypair-uid]) + string/lower-case) account-config {:key-uid (when (= type :generated) key-uid) :wallet false :chat false