feat: integrate max slippage drawer (#21295)

Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
Brian Sztamfater 2024-09-25 16:03:07 -03:00 committed by GitHub
parent 59c2b79df2
commit fdc814cdb0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 18 deletions

View File

@ -148,7 +148,7 @@
colors/neutral-50)] colors/neutral-50)]
[rn/pressable [rn/pressable
{:accessibility-label :data-item {:accessibility-label :data-item
:disabled (not right-icon) :disabled (nil? on-press)
:on-press on-press :on-press on-press
:style (merge (style/container {:size size :style (merge (style/container {:size size
:card? card? :card? card?

View File

@ -591,6 +591,7 @@
(def ^:const slippages [0.1 0.5 1]) (def ^:const slippages [0.1 0.5 1])
(def ^:const default-slippage 0.5) (def ^:const default-slippage 0.5)
(def ^:const max-recommended-slippage 5) (def ^:const max-recommended-slippage 5)
(def ^:const max-slippage 30)
(def ^:const max-slippage-decimal-places 2) (def ^:const max-slippage-decimal-places 2)
(def ^:const swap-provider-paraswap (def ^:const swap-provider-paraswap
{:name :paraswap {:name :paraswap

View File

@ -2,19 +2,24 @@
(:require [clojure.string :as string] (:require [clojure.string :as string]
[quo.core :as quo] [quo.core :as quo]
[react-native.core :as rn] [react-native.core :as rn]
[react-native.platform :as platform]
[status-im.constants :as constants] [status-im.constants :as constants]
[status-im.contexts.wallet.sheets.slippage-settings.style :as style] [status-im.contexts.wallet.sheets.slippage-settings.style :as style]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.number] [utils.money :as money]
[utils.number :as number]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
(defn- validate-slippage (defn- validate-slippage
[slippage] [slippage]
(let [slippage-value (utils.number/parse-float slippage)] (let [slippage-value (number/parse-float slippage)]
(cond (cond
(<= slippage-value 0) (<= slippage-value 0)
{:message (i18n/label :t/slippage-should-be-more-than-0) {:message (i18n/label :t/slippage-should-be-more-than-0)
:type :error} :type :error}
(> slippage-value constants/max-slippage)
{:message (i18n/label :t/slippage-cant-be-more-than-30)
:type :error}
(> (count (second (string/split slippage "."))) (> (count (second (string/split slippage ".")))
constants/max-slippage-decimal-places) constants/max-slippage-decimal-places)
{:message (i18n/label :t/max-2-decimals) {:message (i18n/label :t/max-2-decimals)
@ -33,14 +38,37 @@
(subs s 0 (dec (count s))) (subs s 0 (dec (count s)))
(str s k))) (str s k)))
(defn- calculate-receive-amount
[asset-to-receive amount-out max-slippage]
(let [receive-token-decimals (:decimals asset-to-receive)
amount-out-whole-number (number/hex->whole amount-out receive-token-decimals)
amount-out-num (number/to-fixed amount-out-whole-number
(min constants/min-token-decimals-to-display
receive-token-decimals))
slippage-num (-> (money/bignumber amount-out-num)
(money/mul (money/bignumber max-slippage))
(money/div (money/bignumber 100)))
amount-out-minus-slippage (money/sub (money/bignumber amount-out-num) slippage-num)
receive-amount (if (money/greater-than amount-out-minus-slippage
(money/bignumber 0))
(str amount-out-minus-slippage)
0)]
receive-amount))
(defn view (defn view
[] []
(let [current-slippage (rf/sub [:wallet/swap-max-slippage]) (let [current-slippage (rf/sub [:wallet/swap-max-slippage])
account-color (rf/sub [:wallet/current-viewing-account-color]) account-color (rf/sub [:wallet/current-viewing-account-color])
asset-to-receive (rf/sub [:wallet/swap-asset-to-receive])
amount-out (rf/sub [:wallet/swap-proposal-amount-out])
[max-slippage set-max-slippage] (rn/use-state (str current-slippage)) [max-slippage set-max-slippage] (rn/use-state (str current-slippage))
[error set-error] (rn/use-state nil) [error set-error] (rn/use-state nil)
[custom? set-custom?] (rn/use-state (not-any? #{current-slippage} [custom? set-custom?] (rn/use-state (not-any? #{current-slippage}
constants/slippages)) constants/slippages))
receive-token-symbol (:symbol asset-to-receive)
receive-amount (calculate-receive-amount asset-to-receive
amount-out
max-slippage)
handle-slippage-change (rn/use-callback handle-slippage-change (rn/use-callback
(fn [value] (fn [value]
(let [new-slippage (update-string-on-keypress value (let [new-slippage (update-string-on-keypress value
@ -50,7 +78,8 @@
[max-slippage set-max-slippage set-error]) [max-slippage set-max-slippage set-error])
on-select-slippage (rn/use-callback (fn [slippage] on-select-slippage (rn/use-callback (fn [slippage]
(set-max-slippage (str slippage)) (set-max-slippage (str slippage))
(set-custom? (not slippage))) (set-custom? (nil? slippage))
(when slippage (set-error nil)))
[set-max-slippage set-custom?]) [set-max-slippage set-custom?])
save-disabled? (rn/use-memo (fn [] save-disabled? (rn/use-memo (fn []
(or (= max-slippage (str current-slippage)) (or (= max-slippage (str current-slippage))
@ -73,19 +102,23 @@
[quo/drawer-action [quo/drawer-action
(cond-> {:title (str slippage "%") (cond-> {:title (str slippage "%")
:on-press #(on-select-slippage slippage)} :on-press #(on-select-slippage slippage)}
(= (str slippage) max-slippage) (assoc :state :selected))]) (and (= (str slippage) max-slippage) (not custom?)) (assoc :state :selected))])
constants/slippages) constants/slippages)
[quo/drawer-action [quo/drawer-action
(cond-> {:title (i18n/label :t/custom) (cond-> {:title (i18n/label :t/custom)
:action :input :action :input
:on-press #(on-select-slippage nil) :on-press #(on-select-slippage nil)
:input-props {:auto-focus true :input-props {:auto-focus true
:customization-color account-color :customization-color account-color
:placeholder (i18n/label :t/type-slippage) :placeholder (i18n/label :t/type-slippage)
:right-icon {:icon-name :i/percentage :right-icon {:icon-name :i/percentage
:on-press identity :on-press identity
:style-fn style/percentage-icon} :style-fn style/percentage-icon}
:value max-slippage}} :value max-slippage
:show-soft-input-on-focus false
:on-focus (fn []
(when platform/android?
(rf/dispatch [:dismiss-keyboard])))}}
custom? (assoc :state :selected))]] custom? (assoc :state :selected))]]
(when (and custom? error) (when (and custom? error)
[quo/info-message [quo/info-message
@ -107,8 +140,8 @@
:description :top :description :top
:context-tag-props {:size 24 :context-tag-props {:size 24
:type :token :type :token
:token "USDT" :token receive-token-symbol
:amount "99.97"} ;; will be replaced with real data later :amount receive-amount}
:description-top-text (i18n/label :t/receive-at-least)}] :description-top-text (i18n/label :t/receive-at-least)}]
(when custom? (when custom?
[quo/numbered-keyboard [quo/numbered-keyboard

View File

@ -12,6 +12,7 @@
[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.utils :as utils] [status-im.contexts.wallet.common.utils :as 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.sheets.slippage-settings.view :as slippage-settings]
[status-im.contexts.wallet.swap.setup-swap.style :as style] [status-im.contexts.wallet.swap.setup-swap.style :as style]
[status-im.contexts.wallet.swap.utils :as swap-utils] [status-im.contexts.wallet.swap.utils :as swap-utils]
[utils.debounce :as debounce] [utils.debounce :as debounce]
@ -39,7 +40,7 @@
{:clean-approval-transaction? clean-approval-transaction?}]))) {:clean-approval-transaction? clean-approval-transaction?}])))
(defn- data-item (defn- data-item
[{:keys [title subtitle size subtitle-icon subtitle-color loading?]}] [{:keys [title subtitle size subtitle-icon subtitle-color on-press loading?]}]
[quo/data-item [quo/data-item
{:container-style style/detail-item {:container-style style/detail-item
:blur? false :blur? false
@ -50,7 +51,8 @@
:subtitle subtitle :subtitle subtitle
:size size :size size
:icon subtitle-icon :icon subtitle-icon
:subtitle-color subtitle-color}]) :subtitle-color subtitle-color
:on-press on-press}])
(defn- transaction-details (defn- transaction-details
[] []
@ -72,9 +74,11 @@
theme)))] theme)))]
[data-item [data-item
{:title (i18n/label :t/max-slippage) {:title (i18n/label :t/max-slippage)
:subtitle max-slippage :subtitle (str max-slippage "%")
:subtitle-icon :i/edit :subtitle-icon :i/edit
:size :small}]])) :size :small
:on-press #(rf/dispatch [:show-bottom-sheet
{:content slippage-settings/view}])}]]))
(defn- pay-token-input (defn- pay-token-input
[{:keys [input-state on-max-press on-input-focus on-token-press on-approve-press input-focused?]}] [{:keys [input-state on-max-press on-input-focus on-token-press on-approve-press input-focused?]}]

View File

@ -2320,6 +2320,7 @@
"slide-to-sign": "Slide to sign", "slide-to-sign": "Slide to sign",
"slide-to-swap": "Slide to swap", "slide-to-swap": "Slide to swap",
"slippage": "Slippage", "slippage": "Slippage",
"slippage-cant-be-more-than-30": "Slippage can't be more than 30",
"slippage-may-be-higher-than-necessary": "Slippage may be higher than necessary", "slippage-may-be-higher-than-necessary": "Slippage may be higher than necessary",
"slippage-settings": "Slippage settings", "slippage-settings": "Slippage settings",
"slippage-settings-description": "Your transaction will revert if the price changes more than the slippage percentage", "slippage-settings-description": "Your transaction will revert if the price changes more than the slippage percentage",