Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73d5cb24f8 | ||
|
|
614eeafde9 | ||
|
|
1dc4ea3a51 | ||
|
|
dbef1c9edc | ||
|
|
4853cde20b | ||
|
|
4c5f3282c4 | ||
|
|
376493b0b3 | ||
|
|
886f7b43d1 | ||
|
|
c8c785f136 | ||
|
|
b2602ba15e | ||
|
|
4b0a983d68 | ||
|
|
af5c613cc0 |
+2
-2
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=0
|
|||||||
ETHEREUM_DEV_CLUSTER=0
|
ETHEREUM_DEV_CLUSTER=0
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=error
|
LOG_LEVEL=debug
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
MAINNET_WARNING_ENABLED=1
|
MAINNET_WARNING_ENABLED=1
|
||||||
PFS_ENCRYPTION_ENABLED=1
|
PFS_ENCRYPTION_ENABLED=1
|
||||||
@@ -20,6 +20,6 @@ FAST_CREATE_COMMUNITY_ENABLED=0
|
|||||||
TEST_NETWORKS_ENABLED=0
|
TEST_NETWORKS_ENABLED=0
|
||||||
STATUS_PROXY_STAGE_NAME=prod
|
STATUS_PROXY_STAGE_NAME=prod
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
FLAG_WALLET_CONNECT_ENABLED=1
|
||||||
API_LOGGING_ENABLED=0
|
API_LOGGING_ENABLED=1
|
||||||
SENTRY_ENABLED=1
|
SENTRY_ENABLED=1
|
||||||
SENTRY_ENVIRONMENT=production
|
SENTRY_ENVIRONMENT=production
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
(ns quo.components.buttons.slide-button.constants)
|
(ns quo.components.buttons.slide-button.constants)
|
||||||
|
|
||||||
(def track-padding 4)
|
(def ^:constant small-dimensions
|
||||||
|
|
||||||
(def small-dimensions
|
|
||||||
{:track-height 40
|
{:track-height 40
|
||||||
:thumb 32})
|
:thumb 32})
|
||||||
|
|
||||||
(def large-dimensions
|
(def ^:constant large-dimensions
|
||||||
{:track-height 48
|
{:track-height 48
|
||||||
:thumb 40})
|
:thumb 40})
|
||||||
|
|
||||||
(def disable-opacity 0.3)
|
(def ^:constant track-padding 4)
|
||||||
|
(def ^:constant disable-opacity 0.3)
|
||||||
|
(def ^:constant default-width 300)
|
||||||
|
|
||||||
(def default-width 300)
|
(def ^:constant reset-timeout-ms 500)
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
(when (and reached-end? (not sliding-complete?))
|
(when (and reached-end? (not sliding-complete?))
|
||||||
(set-sliding-complete true)
|
(set-sliding-complete true)
|
||||||
(when on-complete
|
(when on-complete
|
||||||
(on-complete reset-fn))))))
|
(js/setTimeout reset-fn constants/reset-timeout-ms)
|
||||||
|
(on-complete))))))
|
||||||
(gesture/on-end (fn [event]
|
(gesture/on-end (fn [event]
|
||||||
(let [x-translation (oops/oget event "translationX")
|
(let [x-translation (oops/oget event "translationX")
|
||||||
reached-end? (>= x-translation track-width)]
|
reached-end? (>= x-translation track-width)]
|
||||||
@@ -55,10 +56,9 @@
|
|||||||
on-track-layout (rn/use-callback
|
on-track-layout (rn/use-callback
|
||||||
#(set-track-width (oops/oget % "nativeEvent.layout.width")))
|
#(set-track-width (oops/oget % "nativeEvent.layout.width")))
|
||||||
reset-fn (rn/use-callback
|
reset-fn (rn/use-callback
|
||||||
(fn [keep-at-end-after-slide?]
|
(fn []
|
||||||
(set-sliding-complete false)
|
(set-sliding-complete false)
|
||||||
(when-not keep-at-end-after-slide?
|
(animations/reset-track-position x-pos)))
|
||||||
(animations/reset-track-position x-pos))))
|
|
||||||
dimensions (rn/use-callback
|
dimensions (rn/use-callback
|
||||||
(partial utils/get-dimensions
|
(partial utils/get-dimensions
|
||||||
(or track-width constants/default-width)
|
(or track-width constants/default-width)
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
(ns quo.components.common.new-feature-dot
|
||||||
|
(:require [quo.components.common.new-feature-gradient :as new-feature-gradient]))
|
||||||
|
|
||||||
|
(def ^:const size 8)
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[{:keys [style accessibility-label]}]
|
||||||
|
[new-feature-gradient/view
|
||||||
|
{:style (merge {:width size
|
||||||
|
:height size
|
||||||
|
:border-radius (/ size 2)}
|
||||||
|
style)
|
||||||
|
:accessibility-label accessibility-label}])
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
(ns quo.components.common.new-feature-gradient
|
||||||
|
(:require [quo.foundations.colors :as colors]
|
||||||
|
[quo.theme]
|
||||||
|
[react-native.linear-gradient :as linear-gradient]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[{:keys [style accessibility-label]}]
|
||||||
|
(let [theme (quo.theme/use-theme)]
|
||||||
|
[linear-gradient/linear-gradient
|
||||||
|
{:style style
|
||||||
|
:accessibility-label accessibility-label
|
||||||
|
:colors [(colors/resolve-color :yellow theme)
|
||||||
|
colors/new-feature-gradient-pink]
|
||||||
|
:use-angle true
|
||||||
|
:angle 78
|
||||||
|
:angle-center {:x 0.5 :y 0.5}}]))
|
||||||
@@ -33,4 +33,12 @@
|
|||||||
networks-list])
|
networks-list])
|
||||||
(h/is-truthy (h/query-by-label-text :network-dropdown))
|
(h/is-truthy (h/query-by-label-text :network-dropdown))
|
||||||
(h/fire-event :press (h/query-by-label-text :network-dropdown))
|
(h/fire-event :press (h/query-by-label-text :network-dropdown))
|
||||||
(h/was-not-called on-press))))
|
(h/was-not-called on-press)))
|
||||||
|
|
||||||
|
(h/test "Should display new chain indicator"
|
||||||
|
(h/render [network-dropdown/view
|
||||||
|
{:state :default
|
||||||
|
:show-new-chain-indicator? true}
|
||||||
|
networks-list])
|
||||||
|
(h/is-truthy (h/query-by-label-text :network-dropdown))
|
||||||
|
(h/is-truthy (h/query-by-label-text :new-chain-indicator))))
|
||||||
|
|||||||
@@ -23,3 +23,7 @@
|
|||||||
:opacity (if (= state :disabled) 0.3 1)
|
:opacity (if (= state :disabled) 0.3 1)
|
||||||
:border-color (container-border-color props)
|
:border-color (container-border-color props)
|
||||||
:align-items :center})
|
:align-items :center})
|
||||||
|
|
||||||
|
(def new-chain-indicator
|
||||||
|
{:position :absolute
|
||||||
|
:right 0})
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
(ns quo.components.dropdowns.network-dropdown.view
|
(ns quo.components.dropdowns.network-dropdown.view
|
||||||
(:require
|
(:require
|
||||||
|
[quo.components.common.new-feature-dot :as new-feature-dot]
|
||||||
[quo.components.dropdowns.network-dropdown.style :as style]
|
[quo.components.dropdowns.network-dropdown.style :as style]
|
||||||
[quo.components.list-items.preview-list.view :as preview-list]
|
[quo.components.list-items.preview-list.view :as preview-list]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]))
|
[react-native.core :as rn]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [on-press state] :as props} networks]
|
[{:keys [on-press state show-new-chain-indicator?] :as props} networks]
|
||||||
(let [theme (quo.theme/use-theme)
|
(let [theme (quo.theme/use-theme)
|
||||||
[pressed? set-pressed] (rn/use-state false)
|
[pressed? set-pressed] (rn/use-state false)
|
||||||
on-press-in (rn/use-callback #(set-pressed true))
|
on-press-in (rn/use-callback #(set-pressed true))
|
||||||
@@ -18,6 +19,10 @@
|
|||||||
:on-press on-press
|
:on-press on-press
|
||||||
:on-press-in on-press-in
|
:on-press-in on-press-in
|
||||||
:on-press-out on-press-out}
|
:on-press-out on-press-out}
|
||||||
|
(when show-new-chain-indicator?
|
||||||
|
[new-feature-dot/view
|
||||||
|
{:style style/new-chain-indicator
|
||||||
|
:accessibility-label :new-chain-indicator}])
|
||||||
[preview-list/view
|
[preview-list/view
|
||||||
{:type :network
|
{:type :network
|
||||||
:list-size (count networks)
|
:list-size (count networks)
|
||||||
|
|||||||
@@ -200,12 +200,15 @@
|
|||||||
shown-name]]))
|
shown-name]]))
|
||||||
|
|
||||||
(defn- wallet-networks-center
|
(defn- wallet-networks-center
|
||||||
[{:keys [networks networks-on-press background center-content-container-style]}]
|
[{:keys [networks networks-on-press show-new-chain-indicator? background
|
||||||
|
center-content-container-style]}]
|
||||||
[reanimated/view {:style center-content-container-style}
|
[reanimated/view {:style center-content-container-style}
|
||||||
[network-dropdown/view
|
[network-dropdown/view
|
||||||
{:state :default
|
{:state :default
|
||||||
:on-press networks-on-press
|
:on-press networks-on-press
|
||||||
:blur? (= background :blur)} networks]])
|
:blur? (= background :blur)
|
||||||
|
:show-new-chain-indicator? show-new-chain-indicator?}
|
||||||
|
networks]])
|
||||||
|
|
||||||
(defn page-nav
|
(defn page-nav
|
||||||
"Props:
|
"Props:
|
||||||
|
|||||||
@@ -64,3 +64,20 @@
|
|||||||
{:margin-top 7
|
{:margin-top 7
|
||||||
:margin-bottom 2
|
:margin-bottom 2
|
||||||
:margin-left -1})
|
:margin-left -1})
|
||||||
|
|
||||||
|
(def new-feature-tag-container
|
||||||
|
{:margin-left 6
|
||||||
|
:border-radius 12
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
(def new-feature-tag-gradient
|
||||||
|
{:border-radius 12
|
||||||
|
:position :absolute
|
||||||
|
:left 0
|
||||||
|
:right 0
|
||||||
|
:top 0
|
||||||
|
:bottom 0})
|
||||||
|
|
||||||
|
(def new-feature-tag-text
|
||||||
|
{:color colors/white
|
||||||
|
:margin-horizontal 5})
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
[quo.components.avatars.icon-avatar :as icon-avatar]
|
[quo.components.avatars.icon-avatar :as icon-avatar]
|
||||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||||
[quo.components.buttons.button.view :as button]
|
[quo.components.buttons.button.view :as button]
|
||||||
|
[quo.components.common.new-feature-gradient :as new-feature-gradient]
|
||||||
[quo.components.icon :as icon]
|
[quo.components.icon :as icon]
|
||||||
[quo.components.list-items.preview-list.view :as preview-list]
|
[quo.components.list-items.preview-list.view :as preview-list]
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
@@ -115,7 +116,9 @@
|
|||||||
nil)])
|
nil)])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [title on-press action-props accessibility-label blur? container-style content] :as props}]
|
[{:keys [title show-new-feature-tag? on-press action-props accessibility-label blur? container-style
|
||||||
|
content]
|
||||||
|
:as props}]
|
||||||
[rn/pressable
|
[rn/pressable
|
||||||
{:style (merge style/container container-style)
|
{:style (merge style/container container-style)
|
||||||
:on-press (or on-press (:on-change action-props))
|
:on-press (or on-press (:on-change action-props))
|
||||||
@@ -126,10 +129,19 @@
|
|||||||
[rn/view {:style (style/left-sub-container props)}
|
[rn/view {:style (style/left-sub-container props)}
|
||||||
[image-component props]
|
[image-component props]
|
||||||
[rn/view {:style (style/left-container (:image props))}
|
[rn/view {:style (style/left-container (:image props))}
|
||||||
[text/text
|
[rn/view {:flex-direction :row}
|
||||||
{:weight :medium
|
[text/text
|
||||||
:style {:color (when blur? colors/white)}}
|
{:weight :medium
|
||||||
title]
|
:style {:color (when blur? colors/white)}}
|
||||||
|
title]
|
||||||
|
(when show-new-feature-tag?
|
||||||
|
[rn/view {:style style/new-feature-tag-container}
|
||||||
|
[new-feature-gradient/view {:style style/new-feature-tag-gradient}]
|
||||||
|
[text/text
|
||||||
|
{:weight :semi-bold
|
||||||
|
:size :label
|
||||||
|
:style style/new-feature-tag-text}
|
||||||
|
(string/upper-case (i18n/label :t/new))]])]
|
||||||
[description-component props]
|
[description-component props]
|
||||||
[tag-component props]]]
|
[tag-component props]]]
|
||||||
[rn/view {:style (style/sub-container (:alignment action-props))}
|
[rn/view {:style (style/sub-container (:alignment action-props))}
|
||||||
|
|||||||
@@ -88,10 +88,3 @@
|
|||||||
|
|
||||||
(def gradient-end
|
(def gradient-end
|
||||||
(assoc gradient-common :right 0))
|
(assoc gradient-common :right 0))
|
||||||
|
|
||||||
(defn button-loader
|
|
||||||
[theme]
|
|
||||||
{:width 100
|
|
||||||
:height 22
|
|
||||||
:border-radius 6
|
|
||||||
:background-color (loader-color theme)})
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
[:on-input-focus {:optional true} [:maybe fn?]]
|
[:on-input-focus {:optional true} [:maybe fn?]]
|
||||||
[:on-token-press {:optional true} [:maybe fn?]]
|
[:on-token-press {:optional true} [:maybe fn?]]
|
||||||
[:on-max-press {:optional true} [:maybe fn?]]
|
[:on-max-press {:optional true} [:maybe fn?]]
|
||||||
[:max-loading? {:optional true} [:maybe :boolean]]
|
|
||||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||||
[:container-style {:optional true} [:maybe :map]]]]]
|
[:container-style {:optional true} [:maybe :map]]]]]
|
||||||
:any])
|
:any])
|
||||||
@@ -53,7 +52,7 @@
|
|||||||
[{:keys [type status token value fiat-value show-approval-label? error? network-tag-props
|
[{:keys [type status token value fiat-value show-approval-label? error? network-tag-props
|
||||||
approval-label-props default-value auto-focus? input-disabled? enable-swap?
|
approval-label-props default-value auto-focus? input-disabled? enable-swap?
|
||||||
currency-symbol on-change-text show-keyboard? get-ref
|
currency-symbol on-change-text show-keyboard? get-ref
|
||||||
container-style on-swap-press on-token-press on-max-press max-loading? on-input-focus]}]
|
container-style on-swap-press on-token-press on-max-press on-input-focus]}]
|
||||||
(let [theme (quo.theme/use-theme)
|
(let [theme (quo.theme/use-theme)
|
||||||
pay? (= type :pay)
|
pay? (= type :pay)
|
||||||
disabled? (= status :disabled)
|
disabled? (= status :disabled)
|
||||||
@@ -173,13 +172,11 @@
|
|||||||
(when-not loading?
|
(when-not loading?
|
||||||
[:<>
|
[:<>
|
||||||
(when pay?
|
(when pay?
|
||||||
(if max-loading?
|
[rn/pressable {:on-press on-max-press}
|
||||||
[rn/view {:style (style/button-loader theme)}]
|
[network-tag/view
|
||||||
[rn/pressable {:on-press on-max-press}
|
(assoc network-tag-props
|
||||||
[network-tag/view
|
:status
|
||||||
(assoc network-tag-props
|
(if error? :error :default))]])
|
||||||
:status
|
|
||||||
(if error? :error :default))]]))
|
|
||||||
(when fiat-value
|
(when fiat-value
|
||||||
[text/text
|
[text/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
|
|||||||
@@ -18,5 +18,6 @@
|
|||||||
[:dropdown-on-press {:optional true} [:maybe fn?]]
|
[:dropdown-on-press {:optional true} [:maybe fn?]]
|
||||||
[:networks {:optional true}
|
[:networks {:optional true}
|
||||||
[:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]]
|
[:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]]
|
||||||
[:dropdown-state {:optional true} [:maybe [:enum :default :disabled]]]]]]
|
[:dropdown-state {:optional true} [:maybe [:enum :default :disabled]]]
|
||||||
|
[:show-new-chain-indicator? {:optional true} [:maybe :boolean]]]]]
|
||||||
:any])
|
:any])
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
bars))
|
bars))
|
||||||
|
|
||||||
(defn- view-info-top
|
(defn- view-info-top
|
||||||
[{:keys [state balance networks dropdown-on-press dropdown-state]}]
|
[{:keys [state balance networks dropdown-on-press dropdown-state show-new-chain-indicator?]}]
|
||||||
(let [theme (quo.theme/use-theme)]
|
(let [theme (quo.theme/use-theme)]
|
||||||
[rn/view {:style style/container-info-top}
|
[rn/view {:style style/container-info-top}
|
||||||
(if (= state :loading)
|
(if (= state :loading)
|
||||||
@@ -36,9 +36,10 @@
|
|||||||
:style (style/style-text-heading theme)}
|
:style (style/style-text-heading theme)}
|
||||||
balance])
|
balance])
|
||||||
[network-dropdown/view
|
[network-dropdown/view
|
||||||
{:state (or dropdown-state :default)
|
{:state (or dropdown-state :default)
|
||||||
:blur? true
|
:blur? true
|
||||||
:on-press dropdown-on-press}
|
:on-press dropdown-on-press
|
||||||
|
:show-new-chain-indicator? show-new-chain-indicator?}
|
||||||
networks]]))
|
networks]]))
|
||||||
|
|
||||||
(defn- view-metrics
|
(defn- view-metrics
|
||||||
|
|||||||
@@ -315,6 +315,8 @@
|
|||||||
networks-short-name
|
networks-short-name
|
||||||
socials))
|
socials))
|
||||||
|
|
||||||
|
(def new-feature-gradient-pink "#FF33A3")
|
||||||
|
|
||||||
(defn hex-string?
|
(defn hex-string?
|
||||||
[s]
|
[s]
|
||||||
(and (string? s) (string/starts-with? s "#")))
|
(and (string? s) (string/starts-with? s "#")))
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
:auth-button-label auth-button-label}]))
|
:auth-button-label auth-button-label}]))
|
||||||
(vec (conj dependencies on-auth-success on-auth-fail)))
|
(vec (conj dependencies on-auth-success on-auth-fail)))
|
||||||
on-slider-complete (rn/use-callback
|
on-slider-complete (rn/use-callback
|
||||||
(fn [reset-slider-fn]
|
(fn []
|
||||||
(js/setTimeout #(reset-slider-fn false) 500)
|
|
||||||
(if (fn? on-complete)
|
(if (fn? on-complete)
|
||||||
(on-complete)
|
(on-complete)
|
||||||
(on-complete-callback)))
|
(on-complete-callback)))
|
||||||
|
|||||||
@@ -492,16 +492,10 @@
|
|||||||
|
|
||||||
(def ^:const token-for-fees-symbol "ETH")
|
(def ^:const token-for-fees-symbol "ETH")
|
||||||
|
|
||||||
;; The 15% buffer accounts for Ethereum's EIP-1559 fee mechanism, where the base fee can increase
|
|
||||||
;; by up to 12.5% per block in periods of high congestion. The extra 2.5% provides additional
|
|
||||||
;; safety to prevent failed transactions due to rapid gas price fluctuations.
|
|
||||||
(def ^:const eth-max-fee-buffer-percent 15)
|
|
||||||
|
|
||||||
(def ^:const transaction-status-success "Success")
|
(def ^:const transaction-status-success "Success")
|
||||||
(def ^:const transaction-status-pending "Pending")
|
(def ^:const transaction-status-pending "Pending")
|
||||||
(def ^:const transaction-status-failed "Failed")
|
(def ^:const transaction-status-failed "Failed")
|
||||||
|
|
||||||
(def ^:const eth-send-amount-decimal 4)
|
|
||||||
(def ^:const min-token-decimals-to-display 6)
|
(def ^:const min-token-decimals-to-display 6)
|
||||||
(def ^:const swap-proposal-refresh-interval-ms 15000)
|
(def ^:const swap-proposal-refresh-interval-ms 15000)
|
||||||
|
|
||||||
|
|||||||
@@ -275,7 +275,8 @@
|
|||||||
{:events [:chat/unmute-chat-community]}
|
{:events [:chat/unmute-chat-community]}
|
||||||
[{:keys [db]} chat-id]
|
[{:keys [db]} chat-id]
|
||||||
(let [{:keys [community-id]} (get-in db [:chats chat-id])]
|
(let [{:keys [community-id]} (get-in db [:chats chat-id])]
|
||||||
{:db (assoc-in db [:communities community-id :muted] false)}))
|
(when community-id
|
||||||
|
{:db (assoc-in db [:communities community-id :muted] false)})))
|
||||||
|
|
||||||
(rf/defn mute-chat-failed
|
(rf/defn mute-chat-failed
|
||||||
{:events [:chat/mute-failed]}
|
{:events [:chat/mute-failed]}
|
||||||
|
|||||||
@@ -18,11 +18,16 @@
|
|||||||
:padding-horizontal 36
|
:padding-horizontal 36
|
||||||
:padding-vertical 30
|
:padding-vertical 30
|
||||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)}}
|
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)}}
|
||||||
[rn/text {:style {:font-size 26 :color "#9F9FA5" :margin-bottom 36}}
|
[rn/text
|
||||||
|
{:style {:font-size 26
|
||||||
|
:color (colors/theme-colors "#8F8E94" "#9F9FA5" theme)
|
||||||
|
:margin-bottom 36}}
|
||||||
(i18n/label :t/ready-to-scan)]
|
(i18n/label :t/ready-to-scan)]
|
||||||
[rn/image
|
[rn/image {:source (resources/get-image :nfc-prompt)}]
|
||||||
{:source (resources/get-image :nfc-prompt)}]
|
[rn/text
|
||||||
[rn/text {:style {:font-size 16 :color :white :margin-vertical 36}}
|
{:style {:font-size 16
|
||||||
|
:color (colors/theme-colors "#09101C" :white theme)
|
||||||
|
:margin-vertical 36}}
|
||||||
(if connected?
|
(if connected?
|
||||||
(i18n/label :t/connected-dont-move)
|
(i18n/label :t/connected-dont-move)
|
||||||
(i18n/label :t/hold-phone-near-keycard))]
|
(i18n/label :t/hold-phone-near-keycard))]
|
||||||
@@ -32,6 +37,12 @@
|
|||||||
(rf/dispatch [:keycard/hide-connection-sheet]))
|
(rf/dispatch [:keycard/hide-connection-sheet]))
|
||||||
:style {:flex-direction :row}}
|
:style {:flex-direction :row}}
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style {:background-color "#8E8E93" :flex 1 :align-items :center :padding 18 :border-radius 10}}
|
{:style {:background-color (colors/theme-colors "#D5D4DB" "#8E8E93" theme)
|
||||||
[rn/text {:style {:color :white :font-size 16}}
|
:flex 1
|
||||||
|
:align-items :center
|
||||||
|
:padding 18
|
||||||
|
:border-radius 10}}
|
||||||
|
[rn/text
|
||||||
|
{:style {:color (colors/theme-colors "#09101C" :white theme)
|
||||||
|
:font-size 16}}
|
||||||
(i18n/label :t/cancel)]]]]]))
|
(i18n/label :t/cancel)]]]]]))
|
||||||
|
|||||||
+2
-1
@@ -7,6 +7,7 @@
|
|||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||||
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style :as style]
|
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style :as style]
|
||||||
|
[status-im.contexts.wallet.common.utils :as utils]
|
||||||
[status-im.contexts.wallet.common.validation :as validation]
|
[status-im.contexts.wallet.common.validation :as validation]
|
||||||
[utils.address :as utils-address]
|
[utils.address :as utils-address]
|
||||||
[utils.debounce :as debounce]
|
[utils.debounce :as debounce]
|
||||||
@@ -159,7 +160,7 @@
|
|||||||
(fn [clipboard-text]
|
(fn [clipboard-text]
|
||||||
(when-not (string/blank? clipboard-text)
|
(when-not (string/blank? clipboard-text)
|
||||||
(-> clipboard-text
|
(-> clipboard-text
|
||||||
utils-address/extract-address-without-chains-info
|
utils/on-paste-address-or-ens
|
||||||
on-change-text)))))
|
on-change-text)))))
|
||||||
on-press-continue (rn/use-callback
|
on-press-continue (rn/use-callback
|
||||||
(fn []
|
(fn []
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||||
[status-im.contexts.wallet.add-account.add-address-to-watch.style :as style]
|
[status-im.contexts.wallet.add-account.add-address-to-watch.style :as style]
|
||||||
|
[status-im.contexts.wallet.common.utils :as utils]
|
||||||
[status-im.contexts.wallet.common.validation :as validation]
|
[status-im.contexts.wallet.common.validation :as validation]
|
||||||
[status-im.subs.wallet.add-account.address-to-watch]
|
[status-im.subs.wallet.add-account.address-to-watch]
|
||||||
[utils.address :as utils-address]
|
[utils.address :as utils-address]
|
||||||
@@ -42,7 +43,7 @@
|
|||||||
paste-on-input #(clipboard/get-string
|
paste-on-input #(clipboard/get-string
|
||||||
(fn [clipboard-text]
|
(fn [clipboard-text]
|
||||||
(-> clipboard-text
|
(-> clipboard-text
|
||||||
utils.address/extract-address-without-chains-info
|
utils/on-paste-address-or-ens
|
||||||
on-change-text)))]
|
on-change-text)))]
|
||||||
(rn/use-effect (fn []
|
(rn/use-effect (fn []
|
||||||
(when-not (string/blank? scanned-address)
|
(when-not (string/blank? scanned-address)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
(ns status-im.contexts.wallet.common.account-switcher.view
|
(ns status-im.contexts.wallet.common.account-switcher.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
[status-im.contexts.wallet.sheets.account-options.view :as account-options]
|
[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.network-filter.view :as network-filter]
|
||||||
[status-im.contexts.wallet.sheets.select-account.view :as select-account]
|
[status-im.contexts.wallet.sheets.select-account.view :as select-account]
|
||||||
@@ -30,25 +31,33 @@
|
|||||||
type :no-title}}]
|
type :no-title}}]
|
||||||
(let [{:keys [color emoji watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
(let [{:keys [color emoji watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
||||||
networks (rf/sub [:wallet/selected-network-details])
|
networks (rf/sub [:wallet/selected-network-details])
|
||||||
sending-collectible? (rf/sub [:wallet/sending-collectible?])]
|
sending-collectible? (rf/sub [:wallet/sending-collectible?])
|
||||||
|
show-new-chain-indicator? (rf/sub [:wallet/show-new-chain-indicator?])
|
||||||
|
on-press-networks (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:wallet/hide-new-chain-indicator])
|
||||||
|
(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:content network-filter/view}])))]
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
{:type type
|
{:type type
|
||||||
:icon-name icon-name
|
:icon-name icon-name
|
||||||
:margin-top margin-top
|
:margin-top margin-top
|
||||||
:background :blur
|
:background :blur
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:accessibility-label accessibility-label
|
:accessibility-label accessibility-label
|
||||||
:networks networks
|
:networks networks
|
||||||
:align-center? true
|
:align-center? true
|
||||||
:networks-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}])
|
:networks-on-press on-press-networks
|
||||||
:right-side [(when (and (ff/enabled? ::ff/wallet.wallet-connect)
|
:show-new-chain-indicator? show-new-chain-indicator?
|
||||||
(not watch-only?)
|
:right-side [(when (and (ff/enabled? ::ff/wallet.wallet-connect)
|
||||||
show-dapps-button?)
|
(not watch-only?)
|
||||||
{:icon-name :i/dapps
|
show-dapps-button?)
|
||||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])})
|
{:icon-name :i/dapps
|
||||||
(when-not sending-collectible?
|
:on-press #(rf/dispatch [:navigate-to
|
||||||
{:content-type :account-switcher
|
:screen/wallet.connected-dapps])})
|
||||||
:customization-color color
|
(when-not sending-collectible?
|
||||||
:on-press #(on-switcher-press switcher-type params)
|
{:content-type :account-switcher
|
||||||
:emoji emoji
|
:customization-color color
|
||||||
:type (when watch-only? :watch-only)})]}]))
|
:on-press #(on-switcher-press switcher-type params)
|
||||||
|
:emoji emoji
|
||||||
|
:type (when watch-only? :watch-only)})]}]))
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
(:require [quo.core :as quo]
|
(:require [quo.core :as quo]
|
||||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||||
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
|
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
|
||||||
[status-im.contexts.wallet.swap.utils :as swap-utils]
|
|
||||||
[status-im.feature-flags :as ff]
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.money :as money]
|
[utils.money :as money]
|
||||||
@@ -79,34 +78,34 @@
|
|||||||
|
|
||||||
(defn token-value-drawer
|
(defn token-value-drawer
|
||||||
[token watch-only? entry-point]
|
[token watch-only? entry-point]
|
||||||
(let [token-symbol (:token token)
|
(let [token-symbol (:token token)
|
||||||
token-data (rf/sub [:wallet/token-by-symbol-from-first-available-account-with-balance
|
token-data (rf/sub [:wallet/token-by-symbol-from-first-available-account-with-balance
|
||||||
token-symbol])
|
token-symbol])
|
||||||
selected-account (rf/sub [:wallet/current-viewing-account-address])
|
selected-account (rf/sub [:wallet/current-viewing-account-address])
|
||||||
token-owners (rf/sub [:wallet/operable-addresses-with-token-symbol token-symbol])
|
token-owners (rf/sub [:wallet/operable-addresses-with-token-symbol token-symbol])
|
||||||
testnet-mode? (rf/sub [:profile/test-networks-enabled?])
|
testnet-mode? (rf/sub [:profile/test-networks-enabled?])
|
||||||
account-owns-token? (rf/sub [:wallet/current-account-owns-token token-symbol])
|
account-owns-token? (rf/sub [:wallet/current-account-owns-token token-symbol])
|
||||||
network-details (rf/sub [:wallet/network-details])
|
network-details (rf/sub [:wallet/network-details])
|
||||||
token-owned? (if selected-account account-owns-token? (seq token-owners))
|
receive-token-symbol (if (= token-symbol "SNT") "ETH" "SNT")
|
||||||
asset-to-receive (rf/sub [:wallet/token-by-symbol-from-first-available-account-with-balance
|
token-owned? (if selected-account account-owns-token? (seq token-owners))
|
||||||
(swap-utils/default-asset-to-receive token-symbol)])
|
asset-to-receive (rf/sub [:wallet/token-by-symbol receive-token-symbol])
|
||||||
unique-owner? (= (count token-owners) 1)
|
unique-owner? (= (count token-owners) 1)
|
||||||
params (cond-> {:start-flow? true
|
params (cond-> {:start-flow? true
|
||||||
:owners token-owners
|
:owners token-owners
|
||||||
:testnet-mode? testnet-mode?}
|
:testnet-mode? testnet-mode?}
|
||||||
selected-account
|
selected-account
|
||||||
(assoc :token token-data
|
(assoc :token token-data
|
||||||
:stack-id :screen/wallet.accounts
|
:stack-id :screen/wallet.accounts
|
||||||
:has-balance? (-> (get-in token [:values :fiat-unformatted-value])
|
:has-balance? (-> (get-in token [:values :fiat-unformatted-value])
|
||||||
money/above-zero?))
|
money/above-zero?))
|
||||||
(and (not selected-account) unique-owner?)
|
(and (not selected-account) unique-owner?)
|
||||||
(assoc :token-symbol token-symbol
|
(assoc :token-symbol token-symbol
|
||||||
:token token-data
|
:token token-data
|
||||||
:stack-id :wallet-stack)
|
:stack-id :wallet-stack)
|
||||||
|
|
||||||
(and (not selected-account) (not unique-owner?))
|
(and (not selected-account) (not unique-owner?))
|
||||||
(assoc :token-symbol token-symbol
|
(assoc :token-symbol token-symbol
|
||||||
:stack-id :wallet-stack))]
|
:stack-id :wallet-stack))]
|
||||||
[quo/action-drawer
|
[quo/action-drawer
|
||||||
[(cond->> [(when (ff/enabled? ::ff/wallet.assets-modal-manage-tokens)
|
[(cond->> [(when (ff/enabled? ::ff/wallet.assets-modal-manage-tokens)
|
||||||
(action-manage-tokens watch-only?))
|
(action-manage-tokens watch-only?))
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
[status-im.common.qr-codes.view :as qr-codes]
|
[status-im.common.qr-codes.view :as qr-codes]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||||
|
[utils.address]
|
||||||
[utils.money :as money]
|
[utils.money :as money]
|
||||||
[utils.number :as number]
|
[utils.number :as number]
|
||||||
[utils.string]))
|
[utils.string]))
|
||||||
@@ -182,22 +183,12 @@
|
|||||||
[amount display-decimals]
|
[amount display-decimals]
|
||||||
(let [number (or (money/bignumber amount)
|
(let [number (or (money/bignumber amount)
|
||||||
(money/bignumber 0))
|
(money/bignumber 0))
|
||||||
amount-fixed-decimals (-> number
|
amount-fixed-decimals (number/to-fixed number display-decimals)]
|
||||||
(number/format-decimal-fixed display-decimals)
|
|
||||||
(number/remove-trailing-zeroes))]
|
|
||||||
(if (and (= amount-fixed-decimals "0")
|
(if (and (= amount-fixed-decimals "0")
|
||||||
(money/above-zero? amount))
|
(money/above-zero? amount))
|
||||||
(number/small-number-threshold display-decimals)
|
(number/small-number-threshold display-decimals)
|
||||||
(str amount-fixed-decimals))))
|
(str amount-fixed-decimals))))
|
||||||
|
|
||||||
(defn token-balance-for-network
|
|
||||||
"Returns the token balance for a specific chain"
|
|
||||||
[token chain-id]
|
|
||||||
(let [token-decimals (:decimals token)]
|
|
||||||
(-> (get-in token [:balances-per-chain chain-id :raw-balance] 0)
|
|
||||||
(number/convert-to-whole-number token-decimals)
|
|
||||||
money/bignumber)))
|
|
||||||
|
|
||||||
(defn token-balance-display-for-network
|
(defn token-balance-display-for-network
|
||||||
"Formats a token balance for a specific chain and rounds it to a specified number of decimals.
|
"Formats a token balance for a specific chain and rounds it to a specified number of decimals.
|
||||||
If the balance is less than the smallest representable value based on rounding decimals,
|
If the balance is less than the smallest representable value based on rounding decimals,
|
||||||
@@ -334,20 +325,19 @@
|
|||||||
|
|
||||||
(defn make-network-item
|
(defn make-network-item
|
||||||
"This function generates props for quo/category component item"
|
"This function generates props for quo/category component item"
|
||||||
[{:keys [network-name color on-change networks state label-props type blur?]}]
|
[{:keys [network-name color on-change networks label-props type blur?]}]
|
||||||
(cond-> {:title (string/capitalize (name network-name))
|
(cond-> {:title (string/capitalize (name network-name))
|
||||||
:image :icon-avatar
|
:image :icon-avatar
|
||||||
:image-props {:icon (resources/get-network network-name)
|
:image-props {:icon (resources/get-network network-name)
|
||||||
:size :size-20}
|
:size :size-20}
|
||||||
:action :selector
|
;; Remove the following line for v2.35
|
||||||
:action-props {:type (or type
|
:show-new-feature-tag? (= network-name constants/base-network-name)
|
||||||
(if (= :default state)
|
:action :selector
|
||||||
:filled-checkbox
|
:action-props {:type (or type :checkbox)
|
||||||
:checkbox))
|
:blur? blur?
|
||||||
:blur? blur?
|
:customization-color color
|
||||||
:customization-color color
|
:checked? (contains? networks network-name)
|
||||||
:checked? (contains? networks network-name)
|
:on-change on-change}}
|
||||||
:on-change on-change}}
|
|
||||||
|
|
||||||
label-props
|
label-props
|
||||||
(assoc :label :text
|
(assoc :label :text
|
||||||
@@ -491,24 +481,10 @@
|
|||||||
(some positive-balance-in-any-chain? tokens))
|
(some positive-balance-in-any-chain? tokens))
|
||||||
operable-account))))
|
operable-account))))
|
||||||
|
|
||||||
(defn calculate-max-safe-send-amount
|
(defn on-paste-address-or-ens
|
||||||
"Calculates the max ETH that can be sent while reserving enough for gas fees.
|
"Check if the clipboard has any valid address and extract the address without any chain info.
|
||||||
|
If it does not contain an valid address or it is ENS, return the clipboard text as it is"
|
||||||
- Ensures a minimum of 0.0001 ETH and a max of 0.01 ETH for gas.
|
[clipboard-text]
|
||||||
- Uses 20% of the value as an estimated fee, clamped within this range.
|
(if (utils.address/supported-address? clipboard-text)
|
||||||
- In Desktop it's 10% but after some more test, we found 20% is better option.
|
(utils.address/extract-address-without-chains-info clipboard-text)
|
||||||
- Prevents sending the full balance to avoid transaction failures.
|
clipboard-text))
|
||||||
|
|
||||||
Aligned with the desktop logic for consistency.
|
|
||||||
https://github.com/status-im/status-desktop/blob/f320abb5c498ac260a1a4a9db046485b88af81e7/ui/app/AppLayouts/Wallet/WalletUtils.qml#L44"
|
|
||||||
[value]
|
|
||||||
(if (or (nil? value) (zero? value))
|
|
||||||
"0"
|
|
||||||
(let [raw-fee (money/mul (money/bignumber value) 0.2)
|
|
||||||
clamped-fee (money/maximum (money/bignumber 0.0001)
|
|
||||||
(money/minimum (money/bignumber 0.01) raw-fee))
|
|
||||||
result (money/sub (money/bignumber value) clamped-fee)]
|
|
||||||
(-> result
|
|
||||||
(money/maximum 0)
|
|
||||||
(number/format-decimal-fixed constants/eth-send-amount-decimal)
|
|
||||||
(number/remove-trailing-zeroes)))))
|
|
||||||
|
|||||||
@@ -202,7 +202,7 @@
|
|||||||
(is (= (utils/sanitized-token-amount-to-display 0.0001 3) "<0.001"))
|
(is (= (utils/sanitized-token-amount-to-display 0.0001 3) "<0.001"))
|
||||||
(is (= (utils/sanitized-token-amount-to-display 0.00001 3) "<0.001"))
|
(is (= (utils/sanitized-token-amount-to-display 0.00001 3) "<0.001"))
|
||||||
(is (= (utils/sanitized-token-amount-to-display 0 2) "0"))
|
(is (= (utils/sanitized-token-amount-to-display 0 2) "0"))
|
||||||
(is (= (utils/sanitized-token-amount-to-display 123.456789 4) "123.4567"))
|
(is (= (utils/sanitized-token-amount-to-display 123.456789 4) "123.4568"))
|
||||||
(is (= (utils/sanitized-token-amount-to-display 0.00000123 6) "0.000001"))
|
(is (= (utils/sanitized-token-amount-to-display 0.00000123 6) "0.000001"))
|
||||||
(is (= (utils/sanitized-token-amount-to-display nil 2) "0"))
|
(is (= (utils/sanitized-token-amount-to-display nil 2) "0"))
|
||||||
(is (= (utils/sanitized-token-amount-to-display "invalid" 2) "0"))))
|
(is (= (utils/sanitized-token-amount-to-display "invalid" 2) "0"))))
|
||||||
@@ -375,14 +375,3 @@
|
|||||||
{:symbol "DAI"}
|
{:symbol "DAI"}
|
||||||
{:symbol "ETH"}]]
|
{:symbol "ETH"}]]
|
||||||
(is (= (utils/sort-tokens-by-name tokens) expected)))))
|
(is (= (utils/sort-tokens-by-name tokens) expected)))))
|
||||||
|
|
||||||
(deftest calculate-max-safe-send-amount-test
|
|
||||||
(testing "Calculates the max ETH sendable while reserving fees"
|
|
||||||
(is (= "0" (utils/calculate-max-safe-send-amount nil)))
|
|
||||||
(is (= "0" (utils/calculate-max-safe-send-amount 0)))
|
|
||||||
(is (= "0" (utils/calculate-max-safe-send-amount 0.00009)))
|
|
||||||
(is (= "0" (utils/calculate-max-safe-send-amount 0.0001)))
|
|
||||||
(is (= "0.008" (utils/calculate-max-safe-send-amount 0.01)))
|
|
||||||
(is (= "0.99" (utils/calculate-max-safe-send-amount 1.0)))
|
|
||||||
(is (= "9.99" (utils/calculate-max-safe-send-amount 10.0)))
|
|
||||||
(is (= "99.99" (utils/calculate-max-safe-send-amount 100.0)))))
|
|
||||||
|
|||||||
@@ -313,40 +313,3 @@
|
|||||||
(-> collectible
|
(-> collectible
|
||||||
transforms/json->clj
|
transforms/json->clj
|
||||||
transform-collectible))
|
transform-collectible))
|
||||||
|
|
||||||
(defn- bridge-amount-greater-than-bonder-fees?
|
|
||||||
[{{token-decimals :decimals} :from-token
|
|
||||||
bonder-fees :tx-bonder-fees
|
|
||||||
amount-in :amount-in}]
|
|
||||||
(let [bonder-fees (utils.money/token->unit bonder-fees token-decimals)
|
|
||||||
amount-to-bridge (utils.money/token->unit amount-in token-decimals)]
|
|
||||||
(> amount-to-bridge bonder-fees)))
|
|
||||||
|
|
||||||
(defn- remove-multichain-routes
|
|
||||||
[routes]
|
|
||||||
(if (> (count routes) 1)
|
|
||||||
[] ;; if route is multichain, we remove it
|
|
||||||
routes))
|
|
||||||
|
|
||||||
(defn- remove-invalid-bonder-fees-routes
|
|
||||||
[routes]
|
|
||||||
(filter bridge-amount-greater-than-bonder-fees? routes))
|
|
||||||
|
|
||||||
(defn- ->old-route-paths
|
|
||||||
[routes]
|
|
||||||
(map new->old-route-path routes))
|
|
||||||
|
|
||||||
(def ^:private best-routes-fix
|
|
||||||
(comp ->old-route-paths
|
|
||||||
remove-invalid-bonder-fees-routes
|
|
||||||
remove-multichain-routes))
|
|
||||||
|
|
||||||
(def ^:private candidates-fix
|
|
||||||
(comp ->old-route-paths remove-invalid-bonder-fees-routes))
|
|
||||||
|
|
||||||
(defn fix-routes
|
|
||||||
[data]
|
|
||||||
(-> data
|
|
||||||
(rpc->suggested-routes)
|
|
||||||
(update :best best-routes-fix)
|
|
||||||
(update :candidates candidates-fix)))
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[native-module.core :as native-module]
|
[native-module.core :as native-module]
|
||||||
[promesa.core :as promesa]
|
[promesa.core :as promesa]
|
||||||
|
[react-native.async-storage :as async-storage]
|
||||||
[status-im.common.json-rpc.events :as json-rpc]
|
[status-im.common.json-rpc.events :as json-rpc]
|
||||||
[status-im.contexts.profile.recover.effects :as profile.recover.effects]
|
[status-im.contexts.profile.recover.effects :as profile.recover.effects]
|
||||||
[status-im.contexts.wallet.rpc :as wallet-rpc]
|
[status-im.contexts.wallet.rpc :as wallet-rpc]
|
||||||
@@ -130,3 +131,14 @@
|
|||||||
(-> (wallet-rpc/sign-message message address (security/safe-unmask-data password))
|
(-> (wallet-rpc/sign-message message address (security/safe-unmask-data password))
|
||||||
(promesa/then on-success)
|
(promesa/then on-success)
|
||||||
(promesa/catch on-error))))
|
(promesa/catch on-error))))
|
||||||
|
|
||||||
|
(rf/reg-fx
|
||||||
|
:effects.wallet/retrieve-base-chain-indicator-shown
|
||||||
|
(fn []
|
||||||
|
(async-storage/get-item :base-chain-indicator-shown
|
||||||
|
#(rf/dispatch [:wallet/retrieve-new-chain-indicator (not %)]))))
|
||||||
|
|
||||||
|
(rf/reg-fx
|
||||||
|
:effects.wallet/set-base-chain-indicator-shown
|
||||||
|
(fn [flag]
|
||||||
|
(async-storage/set-item! :base-chain-indicator-shown flag)))
|
||||||
|
|||||||
@@ -797,3 +797,14 @@
|
|||||||
:wallet.swap/transaction-success
|
:wallet.swap/transaction-success
|
||||||
:wallet/transaction-success)
|
:wallet/transaction-success)
|
||||||
sent-transactions])]]})))
|
sent-transactions])]]})))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:wallet/retrieve-new-chain-indicator
|
||||||
|
(fn [{:keys [db]} [flag]]
|
||||||
|
{:db (assoc-in db [:wallet :ui :show-new-chain-indicator?] flag)}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:wallet/hide-new-chain-indicator
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
{:db (assoc-in db [:wallet :ui :show-new-chain-indicator?] false)
|
||||||
|
:fx [[:effects.wallet/set-base-chain-indicator-shown true]]}))
|
||||||
|
|||||||
@@ -135,7 +135,13 @@
|
|||||||
cards (conj account-cards-data (new-account-card-data))
|
cards (conj account-cards-data (new-account-card-data))
|
||||||
[init-loaded? set-init-loaded] (rn/use-state false)
|
[init-loaded? set-init-loaded] (rn/use-state false)
|
||||||
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-token-values-and-balance])
|
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-token-values-and-balance])
|
||||||
theme (quo.theme/use-theme)]
|
theme (quo.theme/use-theme)
|
||||||
|
show-new-chain-indicator? (rf/sub [:wallet/show-new-chain-indicator?])
|
||||||
|
on-press-network-selector (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:wallet/hide-new-chain-indicator])
|
||||||
|
(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:content network-filter/view}])))]
|
||||||
(rn/use-effect (fn []
|
(rn/use-effect (fn []
|
||||||
(when (and @account-list-ref (pos? (count cards)))
|
(when (and @account-list-ref (pos? (count cards)))
|
||||||
(.scrollToOffset ^js @account-list-ref
|
(.scrollToOffset ^js @account-list-ref
|
||||||
@@ -157,13 +163,14 @@
|
|||||||
:on-refresh #(rf/dispatch [:wallet/get-accounts])}]
|
:on-refresh #(rf/dispatch [:wallet/get-accounts])}]
|
||||||
:header [rn/view {:style (style/header-container theme)}
|
:header [rn/view {:style (style/header-container theme)}
|
||||||
[quo/wallet-overview
|
[quo/wallet-overview
|
||||||
{:state (if tokens-loading? :loading :default)
|
{:state (if tokens-loading? :loading :default)
|
||||||
:time-frame :none
|
:time-frame :none
|
||||||
:metrics :none
|
:metrics :none
|
||||||
:balance formatted-balance
|
:balance formatted-balance
|
||||||
:networks networks
|
:networks networks
|
||||||
:dropdown-on-press #(rf/dispatch [:show-bottom-sheet
|
:dropdown-on-press on-press-network-selector
|
||||||
{:content network-filter/view}])}]
|
:show-new-chain-indicator? (when (not-empty networks)
|
||||||
|
show-new-chain-indicator?)}]
|
||||||
(when (ff/enabled? ::ff/wallet.graph)
|
(when (ff/enabled? ::ff/wallet.graph)
|
||||||
[quo/wallet-graph {:time-frame :empty}])
|
[quo/wallet-graph {:time-frame :empty}])
|
||||||
[render-cards cards account-list-ref]
|
[render-cards cards account-list-ref]
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.address]
|
[utils.address]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
|
[utils.money :as utils.money]
|
||||||
[utils.number]
|
[utils.number]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[utils.security.core :as security]))
|
[utils.security.core :as security]))
|
||||||
@@ -622,6 +623,43 @@
|
|||||||
{:event :wallet/stop-get-suggested-routes
|
{:event :wallet/stop-get-suggested-routes
|
||||||
:error error}))}]]]}))
|
:error error}))}]]]}))
|
||||||
|
|
||||||
|
(defn- bridge-amount-greater-than-bonder-fees?
|
||||||
|
[{{token-decimals :decimals} :from-token
|
||||||
|
bonder-fees :tx-bonder-fees
|
||||||
|
amount-in :amount-in}]
|
||||||
|
(let [bonder-fees (utils.money/token->unit bonder-fees token-decimals)
|
||||||
|
amount-to-bridge (utils.money/token->unit amount-in token-decimals)]
|
||||||
|
(> amount-to-bridge bonder-fees)))
|
||||||
|
|
||||||
|
(defn- remove-multichain-routes
|
||||||
|
[routes]
|
||||||
|
(if (> (count routes) 1)
|
||||||
|
[] ;; if route is multichain, we remove it
|
||||||
|
routes))
|
||||||
|
|
||||||
|
(defn- remove-invalid-bonder-fees-routes
|
||||||
|
[routes]
|
||||||
|
(filter bridge-amount-greater-than-bonder-fees? routes))
|
||||||
|
|
||||||
|
(defn- ->old-route-paths
|
||||||
|
[routes]
|
||||||
|
(map data-store/new->old-route-path routes))
|
||||||
|
|
||||||
|
(def ^:private best-routes-fix
|
||||||
|
(comp ->old-route-paths
|
||||||
|
remove-invalid-bonder-fees-routes
|
||||||
|
remove-multichain-routes))
|
||||||
|
|
||||||
|
(def ^:private candidates-fix
|
||||||
|
(comp ->old-route-paths remove-invalid-bonder-fees-routes))
|
||||||
|
|
||||||
|
(defn- fix-routes
|
||||||
|
[data]
|
||||||
|
(-> data
|
||||||
|
(data-store/rpc->suggested-routes)
|
||||||
|
(update :best best-routes-fix)
|
||||||
|
(update :candidates candidates-fix)))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:wallet/handle-suggested-routes
|
:wallet/handle-suggested-routes
|
||||||
(fn [{:keys [db]} [data]]
|
(fn [{:keys [db]} [data]]
|
||||||
@@ -647,8 +685,8 @@
|
|||||||
(cond
|
(cond
|
||||||
(and failure? swap?) [:wallet/swap-proposal-error error]
|
(and failure? swap?) [:wallet/swap-proposal-error error]
|
||||||
failure? [:wallet/suggested-routes-error error-message]
|
failure? [:wallet/suggested-routes-error error-message]
|
||||||
swap? [:wallet/swap-proposal-success (data-store/fix-routes data)]
|
swap? [:wallet/swap-proposal-success (fix-routes data)]
|
||||||
:else [:wallet/suggested-routes-success (data-store/fix-routes data)
|
:else [:wallet/suggested-routes-success (fix-routes data)
|
||||||
enough-assets?])]]}))))))
|
enough-assets?])]]}))))))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
:network-name :mainnet
|
:network-name :mainnet
|
||||||
:chain-id 1
|
:chain-id 1
|
||||||
:related-chain-id 5}]
|
:related-chain-id 5}]
|
||||||
|
:wallet/show-new-chain-indicator? false
|
||||||
:wallet/current-viewing-account-address "0x1"
|
:wallet/current-viewing-account-address "0x1"
|
||||||
:wallet/current-viewing-account {:path "m/44'/60'/0'/0/1"
|
:wallet/current-viewing-account {:path "m/44'/60'/0'/0/1"
|
||||||
:emoji "💎"
|
:emoji "💎"
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
(fn [clipboard]
|
(fn [clipboard]
|
||||||
(when-not (empty? clipboard)
|
(when-not (empty? clipboard)
|
||||||
(-> clipboard
|
(-> clipboard
|
||||||
utils-address/extract-address-without-chains-info
|
utils/on-paste-address-or-ens
|
||||||
on-change)))))
|
on-change)))))
|
||||||
:ens-regex constants/regx-ens
|
:ens-regex constants/regx-ens
|
||||||
:scanned-value (or (when recipient-plain-address? send-address) scanned-address)
|
:scanned-value (or (when recipient-plain-address? send-address) scanned-address)
|
||||||
|
|||||||
@@ -8,41 +8,26 @@
|
|||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [selected-networks (rf/sub [:wallet/selected-networks])
|
(let [selected-networks (rf/sub [:wallet/selected-networks])
|
||||||
selector-state (rf/sub [:wallet/network-filter-selector-state])
|
|
||||||
color (rf/sub [:profile/customization-color])
|
color (rf/sub [:profile/customization-color])
|
||||||
network-details (rf/sub [:wallet/network-details])
|
network-details (rf/sub [:wallet/network-details])]
|
||||||
viewing-account? (rf/sub [:wallet/viewing-account?])
|
|
||||||
balance-per-chain (if viewing-account?
|
|
||||||
(rf/sub [:wallet/current-viewing-account-fiat-balance-per-chain])
|
|
||||||
(rf/sub [:wallet/aggregated-fiat-balance-per-chain]))
|
|
||||||
mainnet (first network-details)
|
|
||||||
layer-2-networks (rest network-details)]
|
|
||||||
[:<>
|
[:<>
|
||||||
[quo/drawer-top {:title (i18n/label :t/select-networks)}]
|
[quo/drawer-top {:title (i18n/label :t/select-networks)}]
|
||||||
|
[quo/information-box
|
||||||
|
{:type :informative
|
||||||
|
:icon :i/info
|
||||||
|
:blur? false
|
||||||
|
:style {:margin-horizontal 20
|
||||||
|
:margin-bottom 4}}
|
||||||
|
(i18n/label :t/base-chain-available-info)]
|
||||||
[quo/category
|
[quo/category
|
||||||
{:list-type :settings
|
{:list-type :settings
|
||||||
:data [(utils/make-network-item
|
|
||||||
{:state selector-state
|
|
||||||
:network-name (:network-name mainnet)
|
|
||||||
:color color
|
|
||||||
:networks selected-networks
|
|
||||||
:label-props (get balance-per-chain (:chain-id mainnet))
|
|
||||||
:on-change #(rf/dispatch
|
|
||||||
[:wallet/update-selected-networks
|
|
||||||
(:network-name
|
|
||||||
mainnet)])})]}]
|
|
||||||
[quo/category
|
|
||||||
{:list-type :settings
|
|
||||||
:label (i18n/label :t/layer-2)
|
|
||||||
:data (mapv (fn [network]
|
:data (mapv (fn [network]
|
||||||
(utils/make-network-item
|
(utils/make-network-item
|
||||||
{:state selector-state
|
{:network-name (:network-name network)
|
||||||
:network-name (:network-name network)
|
|
||||||
:color color
|
:color color
|
||||||
:networks selected-networks
|
:networks selected-networks
|
||||||
:label-props (get balance-per-chain (:chain-id network))
|
|
||||||
:on-change #(rf/dispatch
|
:on-change #(rf/dispatch
|
||||||
[:wallet/update-selected-networks
|
[:wallet/update-selected-networks
|
||||||
(:network-name
|
(:network-name
|
||||||
network)])}))
|
network)])}))
|
||||||
layer-2-networks)}]]))
|
network-details)}]]))
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
(:require [re-frame.core :as rf]
|
(:require [re-frame.core :as rf]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.wallet.common.utils :as utils]
|
[status-im.contexts.wallet.common.utils :as utils]
|
||||||
[status-im.contexts.wallet.data-store :as data-store]
|
|
||||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||||
[status-im.contexts.wallet.sheets.network-selection.view :as network-selection]
|
[status-im.contexts.wallet.sheets.network-selection.view :as network-selection]
|
||||||
[status-im.contexts.wallet.swap.utils :as swap-utils]
|
[status-im.contexts.wallet.swap.utils :as swap-utils]
|
||||||
@@ -29,15 +28,6 @@
|
|||||||
:account account
|
:account account
|
||||||
:test-networks-enabled? test-networks-enabled?
|
:test-networks-enabled? test-networks-enabled?
|
||||||
:token-symbol (get-in data [:asset-to-pay :symbol])}))
|
:token-symbol (get-in data [:asset-to-pay :symbol])}))
|
||||||
received-asset (if-not (nil? asset-to-receive)
|
|
||||||
asset-to-receive
|
|
||||||
(swap-utils/select-asset-to-pay-by-symbol
|
|
||||||
{:wallet wallet
|
|
||||||
:account account
|
|
||||||
:test-networks-enabled? test-networks-enabled?
|
|
||||||
:token-symbol (if (= (:symbol asset-to-pay) "SNT")
|
|
||||||
"ETH"
|
|
||||||
"SNT")}))
|
|
||||||
multi-account-balance? (-> available-accounts
|
multi-account-balance? (-> available-accounts
|
||||||
(count)
|
(count)
|
||||||
(> 1))
|
(> 1))
|
||||||
@@ -46,7 +36,7 @@
|
|||||||
start-point (if open-new-screen? :action-menu :swap-button)]
|
start-point (if open-new-screen? :action-menu :swap-button)]
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(assoc-in [:wallet :ui :swap :asset-to-pay] asset-to-pay)
|
(assoc-in [:wallet :ui :swap :asset-to-pay] asset-to-pay)
|
||||||
(assoc-in [:wallet :ui :swap :asset-to-receive] received-asset)
|
(assoc-in [:wallet :ui :swap :asset-to-receive] asset-to-receive)
|
||||||
(assoc-in [:wallet :ui :swap :network] network')
|
(assoc-in [:wallet :ui :swap :network] network')
|
||||||
(assoc-in [:wallet :ui :swap :launch-screen] view-id)
|
(assoc-in [:wallet :ui :swap :launch-screen] view-id)
|
||||||
(assoc-in [:wallet :ui :swap :start-point] start-point))
|
(assoc-in [:wallet :ui :swap :start-point] start-point))
|
||||||
@@ -63,7 +53,7 @@
|
|||||||
[:centralized-metrics/track :metric/swap-start
|
[:centralized-metrics/track :metric/swap-start
|
||||||
{:network (:chain-id network)
|
{:network (:chain-id network)
|
||||||
:pay_token (:symbol asset-to-pay)
|
:pay_token (:symbol asset-to-pay)
|
||||||
:receive_token (:symbol received-asset)
|
:receive_token (:symbol asset-to-receive)
|
||||||
:start_point start-point
|
:start_point start-point
|
||||||
:launch_screen view-id}]]
|
:launch_screen view-id}]]
|
||||||
[:dispatch [:wallet.swap/set-default-slippage]]]
|
[:dispatch [:wallet.swap/set-default-slippage]]]
|
||||||
@@ -77,7 +67,7 @@
|
|||||||
(rf/dispatch
|
(rf/dispatch
|
||||||
[:wallet.swap/start
|
[:wallet.swap/start
|
||||||
{:asset-to-pay asset-to-pay
|
{:asset-to-pay asset-to-pay
|
||||||
:asset-to-receive received-asset
|
:asset-to-receive asset-to-receive
|
||||||
:network network
|
:network network
|
||||||
:open-new-screen?
|
:open-new-screen?
|
||||||
open-new-screen?
|
open-new-screen?
|
||||||
@@ -259,15 +249,13 @@
|
|||||||
|
|
||||||
(rf/reg-event-fx :wallet/stop-get-swap-proposal
|
(rf/reg-event-fx :wallet/stop-get-swap-proposal
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
(let [route-request-ongoing? (some? (get-in db [:wallet :ui :swap :last-request-uuid]))]
|
{:db (update-in db [:wallet :ui :swap] dissoc :last-request-uuid)
|
||||||
(when route-request-ongoing?
|
:json-rpc/call [{:method "wallet_stopSuggestedRoutesAsyncCalculation"
|
||||||
{:db (update-in db [:wallet :ui :swap] dissoc :last-request-uuid)
|
:params []
|
||||||
:json-rpc/call [{:method "wallet_stopSuggestedRoutesAsyncCalculation"
|
:on-error (fn [error]
|
||||||
:params []
|
(log/error "failed to stop fetching swap proposals"
|
||||||
:on-error (fn [error]
|
{:event :wallet/stop-get-swap-proposal
|
||||||
(log/error "failed to stop fetching swap proposals"
|
:error error}))}]}))
|
||||||
{:event :wallet/stop-get-swap-proposal
|
|
||||||
:error error}))}]}))))
|
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:wallet/clean-swap-proposal
|
:wallet/clean-swap-proposal
|
||||||
@@ -587,82 +575,3 @@
|
|||||||
[:dispatch
|
[:dispatch
|
||||||
[:navigate-to-within-stack
|
[:navigate-to-within-stack
|
||||||
[:screen/wallet.swap-select-asset-to-pay :screen/wallet.swap-select-account]]]])})))
|
[:screen/wallet.swap-select-asset-to-pay :screen/wallet.swap-select-account]]]])})))
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/get-swap-proposal-fee
|
|
||||||
(fn [{:keys [db]} [{:keys [amount-in amount-out]}]]
|
|
||||||
(let [wallet-address (get-in db [:wallet :current-viewing-account-address])
|
|
||||||
{:keys [asset-to-pay asset-to-receive
|
|
||||||
network]} (get-in db [:wallet :ui :swap])
|
|
||||||
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
|
||||||
networks ((if test-networks-enabled? :test :prod)
|
|
||||||
(get-in db [:wallet :networks]))
|
|
||||||
network-chain-ids (map :chain-id networks)
|
|
||||||
pay-token-decimal (:decimals asset-to-pay)
|
|
||||||
pay-token-id (:symbol asset-to-pay)
|
|
||||||
receive-token-id (:symbol asset-to-receive)
|
|
||||||
receive-token-decimals (:decimals asset-to-receive)
|
|
||||||
gas-rates constants/gas-rate-medium
|
|
||||||
amount-in-hex (if amount-in
|
|
||||||
(send-utils/amount-in-hex amount-in pay-token-decimal)
|
|
||||||
0)
|
|
||||||
amount-out-hex (when amount-out
|
|
||||||
(send-utils/amount-in-hex amount-out receive-token-decimals))
|
|
||||||
to-address wallet-address
|
|
||||||
from-address wallet-address
|
|
||||||
swap-chain-id (:chain-id network)
|
|
||||||
disabled-to-chain-ids (filter #(not= % swap-chain-id) network-chain-ids)
|
|
||||||
disabled-from-chain-ids (filter #(not= % swap-chain-id) network-chain-ids)
|
|
||||||
from-locked-amount {}
|
|
||||||
send-type constants/send-type-swap
|
|
||||||
request-uuid (str (random-uuid))
|
|
||||||
params [(cond->
|
|
||||||
{:uuid request-uuid
|
|
||||||
:sendType send-type
|
|
||||||
:addrFrom from-address
|
|
||||||
:addrTo to-address
|
|
||||||
:tokenID pay-token-id
|
|
||||||
:toTokenID receive-token-id
|
|
||||||
:disabledFromChainIDs disabled-from-chain-ids
|
|
||||||
:disabledToChainIDs disabled-to-chain-ids
|
|
||||||
:gasFeeMode gas-rates
|
|
||||||
:fromLockedAmount from-locked-amount
|
|
||||||
:amountOut (or amount-out-hex "0x0")}
|
|
||||||
amount-in (assoc :amountIn amount-in-hex))]]
|
|
||||||
{:db (assoc-in db [:wallet :ui :swap :loading-swap-proposal-fee?] true)
|
|
||||||
:json-rpc/call [{:method "wallet_getSuggestedRoutes"
|
|
||||||
:params params
|
|
||||||
:on-success (fn [data]
|
|
||||||
(let [swap-proposal (data-store/fix-routes data)]
|
|
||||||
(rf/dispatch [:wallet/swap-proposal-fee-success
|
|
||||||
swap-proposal])))
|
|
||||||
:on-error (fn [error]
|
|
||||||
(rf/dispatch [:wallet/swap-proposal-fee-error])
|
|
||||||
(log/error "failed to get suggested routes"
|
|
||||||
{:event :wallet/get-swap-proposal-fee
|
|
||||||
:error (:message error)
|
|
||||||
:params params}))}]})))
|
|
||||||
|
|
||||||
(rf/reg-event-fx
|
|
||||||
:wallet/swap-proposal-fee-success
|
|
||||||
(fn [{:keys [db]} [swap-proposal]]
|
|
||||||
(let [best-routes (:best swap-proposal)
|
|
||||||
selected-route (first best-routes)
|
|
||||||
relevant-fee-fields [:gas-amount :gas-fees :token-fees :approval-required
|
|
||||||
:approval-fee :approval-l-1-fee :bonder-fees]
|
|
||||||
fee-data (select-keys selected-route relevant-fee-fields)]
|
|
||||||
{:db (update-in db
|
|
||||||
[:wallet :ui :swap]
|
|
||||||
assoc
|
|
||||||
:loading-swap-proposal-fee? false
|
|
||||||
:swap-proposal
|
|
||||||
(when-not (empty? best-routes)
|
|
||||||
fee-data))})))
|
|
||||||
|
|
||||||
(rf/reg-event-fx
|
|
||||||
:wallet/swap-proposal-fee-error
|
|
||||||
(fn [{:keys [db]}]
|
|
||||||
{:db (update-in db
|
|
||||||
[:wallet :ui :swap]
|
|
||||||
assoc
|
|
||||||
:loading-swap-proposal-fee?
|
|
||||||
false)}))
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
||||||
[status-im.contexts.wallet.common.asset-list.view :as asset-list]
|
[status-im.contexts.wallet.common.asset-list.view :as asset-list]
|
||||||
[status-im.contexts.wallet.swap.select-asset-to-pay.style :as style]
|
[status-im.contexts.wallet.swap.select-asset-to-pay.style :as style]
|
||||||
[status-im.contexts.wallet.swap.utils :as swap-utils]
|
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
@@ -21,11 +20,11 @@
|
|||||||
|
|
||||||
(defn- assets-view
|
(defn- assets-view
|
||||||
[search-text on-change-text]
|
[search-text on-change-text]
|
||||||
(let [on-token-press (fn [token]
|
(let [snt-token (rf/sub [:wallet/token-by-symbol "SNT"])
|
||||||
|
eth-token (rf/sub [:wallet/token-by-symbol "ETH"])
|
||||||
|
on-token-press (fn [token]
|
||||||
(let [pay-token-symbol (:symbol token)
|
(let [pay-token-symbol (:symbol token)
|
||||||
asset-to-receive (rf/sub [:wallet/token-by-symbol
|
asset-to-receive (if (= pay-token-symbol "SNT") eth-token snt-token)]
|
||||||
(swap-utils/default-asset-to-receive
|
|
||||||
pay-token-symbol)])]
|
|
||||||
(rf/dispatch [:wallet.swap/start
|
(rf/dispatch [:wallet.swap/start
|
||||||
{:asset-to-pay {:symbol pay-token-symbol}
|
{:asset-to-pay {:symbol pay-token-symbol}
|
||||||
:asset-to-receive asset-to-receive
|
:asset-to-receive asset-to-receive
|
||||||
|
|||||||
@@ -115,7 +115,6 @@
|
|||||||
pay-token-symbol (rf/sub [:wallet/swap-asset-to-pay-symbol])
|
pay-token-symbol (rf/sub [:wallet/swap-asset-to-pay-symbol])
|
||||||
pay-token-decimals (rf/sub [:wallet/swap-asset-to-pay-decimals])
|
pay-token-decimals (rf/sub [:wallet/swap-asset-to-pay-decimals])
|
||||||
loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||||
loading-swap-proposal-fee? (rf/sub [:wallet/swap-loading-swap-proposal-fee?])
|
|
||||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||||
approval-required (rf/sub [:wallet/swap-proposal-approval-required])
|
approval-required (rf/sub [:wallet/swap-proposal-approval-required])
|
||||||
approval-amount-required (rf/sub [:wallet/swap-proposal-approval-amount-required])
|
approval-amount-required (rf/sub [:wallet/swap-proposal-approval-amount-required])
|
||||||
@@ -123,7 +122,6 @@
|
|||||||
approval-transaction-id (rf/sub [:wallet/swap-approval-transaction-id])
|
approval-transaction-id (rf/sub [:wallet/swap-approval-transaction-id])
|
||||||
approved-amount (rf/sub [:wallet/swap-approved-amount])
|
approved-amount (rf/sub [:wallet/swap-approved-amount])
|
||||||
error-response (rf/sub [:wallet/swap-error-response])
|
error-response (rf/sub [:wallet/swap-error-response])
|
||||||
eth-proposal? (= pay-token-symbol "ETH")
|
|
||||||
overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))
|
overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))
|
||||||
input-ref (rn/use-ref-atom nil)
|
input-ref (rn/use-ref-atom nil)
|
||||||
set-input-ref (rn/use-callback (fn [ref] (reset! input-ref ref)))
|
set-input-ref (rn/use-callback (fn [ref] (reset! input-ref ref)))
|
||||||
@@ -133,16 +131,12 @@
|
|||||||
(:chain-id network)])
|
(:chain-id network)])
|
||||||
pay-token-fiat-value (rf/sub [:wallet/swap-asset-to-pay-amount-in-fiat
|
pay-token-fiat-value (rf/sub [:wallet/swap-asset-to-pay-amount-in-fiat
|
||||||
pay-input-num-value])
|
pay-input-num-value])
|
||||||
available-crypto-limit (rf/sub [:wallet/swap-available-crypto-limit])
|
available-crypto-limit (money/bignumber
|
||||||
display-decimals (min pay-token-decimals
|
|
||||||
(if eth-proposal?
|
|
||||||
constants/eth-send-amount-decimal
|
|
||||||
constants/min-token-decimals-to-display))
|
|
||||||
total-crypto-limit (money/bignumber
|
|
||||||
pay-token-balance-selected-chain)
|
pay-token-balance-selected-chain)
|
||||||
total-crypto-limit-display (utils/sanitized-token-amount-to-display
|
display-decimals (min pay-token-decimals
|
||||||
total-crypto-limit
|
constants/min-token-decimals-to-display)
|
||||||
display-decimals)
|
available-crypto-limit-display (rf/sub [:wallet/swap-asset-to-pay-balance-for-chain-ui
|
||||||
|
(:chain-id network)])
|
||||||
approval-amount-required-num (when approval-amount-required
|
approval-amount-required-num (when approval-amount-required
|
||||||
(number/to-fixed (number/hex->whole
|
(number/to-fixed (number/hex->whole
|
||||||
approval-amount-required
|
approval-amount-required
|
||||||
@@ -163,36 +157,14 @@
|
|||||||
pay-input-amount))
|
pay-input-amount))
|
||||||
(> pay-input-amount 0)
|
(> pay-input-amount 0)
|
||||||
(not pay-input-error?))
|
(not pay-input-error?))
|
||||||
request-swap-proposal-fee (rn/use-callback
|
|
||||||
(fn []
|
|
||||||
(let [safe-send-amount (utils/calculate-max-safe-send-amount
|
|
||||||
pay-token-balance-selected-chain)]
|
|
||||||
(rf/dispatch [:wallet/get-swap-proposal-fee
|
|
||||||
{:amount-in safe-send-amount}])))
|
|
||||||
[pay-token-balance-selected-chain])
|
|
||||||
request-fetch-swap-proposal (rn/use-callback
|
request-fetch-swap-proposal (rn/use-callback
|
||||||
(fn []
|
(fn []
|
||||||
(fetch-swap-proposal
|
(fetch-swap-proposal
|
||||||
{:amount pay-input-amount
|
{:amount pay-input-amount
|
||||||
:valid-input? valid-pay-input?
|
:valid-input? valid-pay-input?
|
||||||
:clean-approval-transaction? true}))
|
:clean-approval-transaction? true}))
|
||||||
[pay-input-amount])
|
[pay-input-amount])]
|
||||||
on-max-balance-press (rn/use-callback
|
|
||||||
(fn []
|
|
||||||
(let [max-value (if eth-proposal?
|
|
||||||
(number/format-decimal-fixed
|
|
||||||
available-crypto-limit
|
|
||||||
constants/eth-send-amount-decimal)
|
|
||||||
(money/to-string available-crypto-limit))]
|
|
||||||
(when (money/greater-than max-value 0)
|
|
||||||
(on-max-press max-value))))
|
|
||||||
[available-crypto-limit eth-proposal?])]
|
|
||||||
(rn/use-unmount #(rf/dispatch [:wallet/clean-swap]))
|
(rn/use-unmount #(rf/dispatch [:wallet/clean-swap]))
|
||||||
(rn/use-effect
|
|
||||||
(fn []
|
|
||||||
(when eth-proposal?
|
|
||||||
(request-swap-proposal-fee)))
|
|
||||||
[eth-proposal?])
|
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(request-fetch-swap-proposal))
|
(request-fetch-swap-proposal))
|
||||||
@@ -224,13 +196,12 @@
|
|||||||
input-focused? :typing
|
input-focused? :typing
|
||||||
:else :disabled)
|
:else :disabled)
|
||||||
:on-token-press on-token-press
|
:on-token-press on-token-press
|
||||||
:on-max-press on-max-balance-press
|
:on-max-press #(on-max-press (str pay-token-balance-selected-chain))
|
||||||
:max-loading? loading-swap-proposal-fee?
|
|
||||||
:on-input-focus on-input-focus
|
:on-input-focus on-input-focus
|
||||||
:value pay-input-amount
|
:value pay-input-amount
|
||||||
:fiat-value pay-token-fiat-value
|
:fiat-value pay-token-fiat-value
|
||||||
:network-tag-props {:title (i18n/label :t/max-token
|
:network-tag-props {:title (i18n/label :t/max-token
|
||||||
{:number total-crypto-limit-display
|
{:number available-crypto-limit-display
|
||||||
:token-symbol pay-token-symbol})
|
:token-symbol pay-token-symbol})
|
||||||
:networks [{:source (:source network)}]}
|
:networks [{:source (:source network)}]}
|
||||||
:approval-label-props {:status (case approval-transaction-status
|
:approval-label-props {:status (case approval-transaction-status
|
||||||
@@ -331,16 +302,16 @@
|
|||||||
|
|
||||||
(defn- action-button
|
(defn- action-button
|
||||||
[{:keys [on-press]}]
|
[{:keys [on-press]}]
|
||||||
(let [account-color (rf/sub [:wallet/current-viewing-account-color])
|
(let [account-color (rf/sub [:wallet/current-viewing-account-color])
|
||||||
swap-proposal-received-amount (rf/sub [:wallet/swap-proposal-amount-out])
|
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||||
error-response (rf/sub [:wallet/swap-error-response])
|
error-response (rf/sub [:wallet/swap-error-response])
|
||||||
loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||||
approval-required? (rf/sub [:wallet/swap-proposal-approval-required])
|
approval-required? (rf/sub [:wallet/swap-proposal-approval-required])
|
||||||
approval-transaction-status (rf/sub [:wallet/swap-approval-transaction-status])]
|
approval-transaction-status (rf/sub [:wallet/swap-approval-transaction-status])]
|
||||||
[quo/bottom-actions
|
[quo/bottom-actions
|
||||||
{:actions :one-action
|
{:actions :one-action
|
||||||
:button-one-label (i18n/label :t/review-swap)
|
:button-one-label (i18n/label :t/review-swap)
|
||||||
:button-one-props {:disabled? (or (not swap-proposal-received-amount)
|
:button-one-props {:disabled? (or (not swap-proposal)
|
||||||
error-response
|
error-response
|
||||||
(and approval-required?
|
(and approval-required?
|
||||||
(not= approval-transaction-status :confirmed))
|
(not= approval-transaction-status :confirmed))
|
||||||
|
|||||||
@@ -62,9 +62,3 @@
|
|||||||
[{:keys [networks]}]
|
[{:keys [networks]}]
|
||||||
(when (= (count networks) 1)
|
(when (= (count networks) 1)
|
||||||
(first networks)))
|
(first networks)))
|
||||||
|
|
||||||
(defn default-asset-to-receive
|
|
||||||
[pay-token-symbol]
|
|
||||||
(cond (= pay-token-symbol "SNT") "ETH"
|
|
||||||
(= pay-token-symbol "ETH") "USDC"
|
|
||||||
:else "SNT"))
|
|
||||||
|
|||||||
@@ -78,4 +78,6 @@
|
|||||||
;;app starting flow continues in get-profiles-overview
|
;;app starting flow continues in get-profiles-overview
|
||||||
:profile/get-profiles-overview #(rf/dispatch [:profile/get-profiles-overview-success %])
|
:profile/get-profiles-overview #(rf/dispatch [:profile/get-profiles-overview-success %])
|
||||||
:effects.font/get-font-file-for-initials-avatar
|
:effects.font/get-font-file-for-initials-avatar
|
||||||
#(rf/dispatch [:font/init-font-file-for-initials-avatar %])}))
|
#(rf/dispatch [:font/init-font-file-for-initials-avatar %])
|
||||||
|
;; show new chain indicator to highlight base chain. This will be be removed in v2.35.
|
||||||
|
:effects.wallet/retrieve-base-chain-indicator-shown nil}))
|
||||||
|
|||||||
@@ -142,11 +142,6 @@
|
|||||||
:<- [:wallet/swap]
|
:<- [:wallet/swap]
|
||||||
:-> :loading-swap-proposal?)
|
:-> :loading-swap-proposal?)
|
||||||
|
|
||||||
(rf/reg-sub
|
|
||||||
:wallet/swap-loading-swap-proposal-fee?
|
|
||||||
:<- [:wallet/swap]
|
|
||||||
:-> :loading-swap-proposal-fee?)
|
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/swap-transaction-for-signing
|
:wallet/swap-transaction-for-signing
|
||||||
:<- [:wallet/swap]
|
:<- [:wallet/swap]
|
||||||
@@ -378,28 +373,3 @@
|
|||||||
:token asset-to-pay
|
:token asset-to-pay
|
||||||
:prices-per-token prices-per-token})]
|
:prices-per-token prices-per-token})]
|
||||||
(utils/fiat-formatted-for-ui currency-symbol fiat-value)))))
|
(utils/fiat-formatted-for-ui currency-symbol fiat-value)))))
|
||||||
|
|
||||||
(rf/reg-sub :wallet/max-swap-fee
|
|
||||||
:<- [:wallet/swap-proposal-approval-required]
|
|
||||||
:<- [:wallet/swap-approval-fee]
|
|
||||||
:<- [:wallet/swap-proposal]
|
|
||||||
(fn [[approval-required swap-approval-fee swap-proposal]]
|
|
||||||
(let [wallet-swap-proposal-fee (send-utils/full-route-gas-fee [swap-proposal])]
|
|
||||||
(if approval-required
|
|
||||||
(money/add swap-approval-fee wallet-swap-proposal-fee)
|
|
||||||
wallet-swap-proposal-fee))))
|
|
||||||
|
|
||||||
(rf/reg-sub :wallet/swap-available-crypto-limit
|
|
||||||
:<- [:wallet/swap-network]
|
|
||||||
:<- [:wallet/swap-asset-to-pay-balance-for-chain-data]
|
|
||||||
:<- [:wallet/max-swap-fee]
|
|
||||||
:<- [:wallet/swap-asset-to-pay-symbol]
|
|
||||||
(fn [[network asset-to-pay-with-current-account-balance max-swap-fee pay-token-symbol]]
|
|
||||||
(let [pay-token-balance (utils/token-balance-for-network
|
|
||||||
asset-to-pay-with-current-account-balance
|
|
||||||
(:chain-id network))]
|
|
||||||
(if (= pay-token-symbol constants/token-for-fees-symbol)
|
|
||||||
(let [buffered-fee (money/mul max-swap-fee
|
|
||||||
(inc (/ constants/eth-max-fee-buffer-percent 100)))]
|
|
||||||
(money/sub pay-token-balance buffered-fee))
|
|
||||||
pay-token-balance))))
|
|
||||||
|
|||||||
@@ -47,6 +47,11 @@
|
|||||||
:<- [:wallet/ui]
|
:<- [:wallet/ui]
|
||||||
:-> :last-updates-per-address)
|
:-> :last-updates-per-address)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/show-new-chain-indicator?
|
||||||
|
:<- [:wallet/ui]
|
||||||
|
:-> :show-new-chain-indicator?)
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/latest-update
|
:wallet/latest-update
|
||||||
:<- [:wallet/last-updates-per-address]
|
:<- [:wallet/last-updates-per-address]
|
||||||
|
|||||||
@@ -246,13 +246,3 @@
|
|||||||
(schema/=> format-amount
|
(schema/=> format-amount
|
||||||
[:=> [:cat [:maybe :int]]
|
[:=> [:cat [:maybe :int]]
|
||||||
[:maybe :string]])
|
[:maybe :string]])
|
||||||
|
|
||||||
(defn maximum
|
|
||||||
[n1 n2]
|
|
||||||
(when-let [[^js bn1 ^js bn2] (->bignumbers n1 n2)]
|
|
||||||
(if (greater-than-or-equals bn1 bn2) bn1 bn2)))
|
|
||||||
|
|
||||||
(defn minimum
|
|
||||||
[n1 n2]
|
|
||||||
(when-let [[^js bn1 ^js bn2] (->bignumbers n1 n2)]
|
|
||||||
(if (less-than bn1 bn2) bn1 bn2)))
|
|
||||||
|
|||||||
@@ -97,18 +97,3 @@
|
|||||||
[num decimal-count]
|
[num decimal-count]
|
||||||
(let [decimal-part (second (string/split (str num) #"\."))]
|
(let [decimal-part (second (string/split (str num) #"\."))]
|
||||||
(or (nil? decimal-part) (<= (count decimal-part) decimal-count))))
|
(or (nil? decimal-part) (<= (count decimal-part) decimal-count))))
|
||||||
|
|
||||||
(defn format-decimal-fixed
|
|
||||||
"Formats a number `n` to `decimal-places` without rounding.
|
|
||||||
- Ensures the exact number of decimal places (including trailing zeros).
|
|
||||||
- Does not round up or down, just trims excess decimals."
|
|
||||||
[n decimal-places]
|
|
||||||
(let [bn (money/bignumber n)
|
|
||||||
scale (money/bignumber (money/from-decimal decimal-places))
|
|
||||||
truncated (if (money/less-than bn 0)
|
|
||||||
(Math/ceil (money/mul bn scale))
|
|
||||||
(Math/floor (money/mul bn scale)))]
|
|
||||||
(-> truncated
|
|
||||||
(money/bignumber)
|
|
||||||
(money/div scale)
|
|
||||||
(money/to-fixed decimal-places))))
|
|
||||||
|
|||||||
@@ -88,19 +88,3 @@
|
|||||||
|
|
||||||
(is (true? (utils.number/valid-decimal-count? 1234567890.12 2)))
|
(is (true? (utils.number/valid-decimal-count? 1234567890.12 2)))
|
||||||
(is (false? (utils.number/valid-decimal-count? 1234567890.12345 3)))))
|
(is (false? (utils.number/valid-decimal-count? 1234567890.12345 3)))))
|
||||||
|
|
||||||
(deftest format-decimal-fixed-test
|
|
||||||
(testing "Format decimal numbers correctly without rounding"
|
|
||||||
(is (= "123.45" (utils.number/format-decimal-fixed "123.456" 2)))
|
|
||||||
(is (= "123.456" (utils.number/format-decimal-fixed "123.456" 3)))
|
|
||||||
|
|
||||||
(is (= "123.45600" (utils.number/format-decimal-fixed "123.456" 5)))
|
|
||||||
(is (= "123.000" (utils.number/format-decimal-fixed "123.000" 3)))
|
|
||||||
|
|
||||||
(is (= "123" (utils.number/format-decimal-fixed "123.999" 0)))
|
|
||||||
|
|
||||||
(is (= "-123.4" (utils.number/format-decimal-fixed "-123.456" 1)))
|
|
||||||
(is (= "-123.45" (utils.number/format-decimal-fixed "-123.456" 2)))
|
|
||||||
|
|
||||||
(is (= "0.0006" (utils.number/format-decimal-fixed "0.000650462672354754" 4)))
|
|
||||||
(is (= "999999999.999" (utils.number/format-decimal-fixed "999999999.999999" 3)))))
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v10.8.0",
|
"version": "v10.7.0+hotfix.2",
|
||||||
"commit-sha1": "ba8fd51958686aea45e34e684ac925a4e65927f8",
|
"commit-sha1": "595dc68e9ff5e6e57364818098616a97b83eabd5",
|
||||||
"src-sha256": "0kqn5rkfsn7aqc2n2flqvkm6cc53ssk0mc1l84f4czg0paci0717"
|
"src-sha256": "04dsmz70h3i738bj3i3ba8bckpw61vxb56m8sc4qw8agc9pdaxc0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class TestWalletCollectibles(MultipleSharedDeviceTestCase):
|
|||||||
@marks.testrail_id(741839)
|
@marks.testrail_id(741839)
|
||||||
def test_wallet_collectibles_balance(self):
|
def test_wallet_collectibles_balance(self):
|
||||||
self.wallet_view.collectibles_tab.click()
|
self.wallet_view.collectibles_tab.click()
|
||||||
self.wallet_view.set_network_in_wallet(self.network_name)
|
self.wallet_view.set_network_in_wallet(self.network_name + ', NEW')
|
||||||
collectibles = {
|
collectibles = {
|
||||||
"BVL": {"quantity": 2,
|
"BVL": {"quantity": 2,
|
||||||
"info": {"Account": "Account 1",
|
"info": {"Account": "Account 1",
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
|
|||||||
'Mainnet': self.mainnet_balance,
|
'Mainnet': self.mainnet_balance,
|
||||||
'Arbitrum': self.arb_balance,
|
'Arbitrum': self.arb_balance,
|
||||||
'Optimism': self.optimism_balance,
|
'Optimism': self.optimism_balance,
|
||||||
'Base': self.base_balance
|
'Base, NEW': self.base_balance
|
||||||
}
|
}
|
||||||
|
|
||||||
for network in expected_balances:
|
for network in expected_balances:
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ class WalletView(BaseView):
|
|||||||
|
|
||||||
def set_network_in_wallet(self, network_name: str):
|
def set_network_in_wallet(self, network_name: str):
|
||||||
self.network_drop_down.click()
|
self.network_drop_down.click()
|
||||||
Button(self.driver, accessibility_id="%s, label-component" % network_name.capitalize()).click()
|
Button(self.driver, accessibility_id="%s, label-component" % network_name).click()
|
||||||
self.network_drop_down.click()
|
self.network_drop_down.click()
|
||||||
|
|
||||||
def get_account_element(self, account_name: str = 'Account 1'):
|
def get_account_element(self, account_name: str = 'Account 1'):
|
||||||
|
|||||||
@@ -200,6 +200,7 @@
|
|||||||
"bad-fees-description": "Your priority fee is below our suggested parameters.",
|
"bad-fees-description": "Your priority fee is below our suggested parameters.",
|
||||||
"balance": "Balance",
|
"balance": "Balance",
|
||||||
"base": "Base",
|
"base": "Base",
|
||||||
|
"base-chain-available-info": "Base chain is now on Status - view your assets, interact with dApps and swap tokens",
|
||||||
"be-safe-with-secure-cold-wallet": "Be safe with secure cold wallet",
|
"be-safe-with-secure-cold-wallet": "Be safe with secure cold wallet",
|
||||||
"begin-set-up": "Begin setup",
|
"begin-set-up": "Begin setup",
|
||||||
"below-base-fee": "max fee below base fee",
|
"below-base-fee": "max fee below base fee",
|
||||||
|
|||||||
Reference in New Issue
Block a user