Compare commits

..
21 changed files with 115 additions and 360 deletions
+12 -3
View File
@@ -109,10 +109,19 @@ pipeline {
stage('Upload') { stage('Upload') {
steps { script { steps { script {
sshagent(credentials: ['nix-cache-ssh']) { sshagent(credentials: ['nix-cache-ssh']) {
nix.shell(""" nix.shell(
"""
find /nix/store/ -mindepth 1 -maxdepth 1 -type d \ find /nix/store/ -mindepth 1 -maxdepth 1 -type d \
-not -name '*.links' -and -not -name '*-status-mobile-*' \ -not -name "*.links" -and -not -name "*-status-mobile-*" \
| xargs nix copy --to ${NIX_SSH_REMOTE} -and -not -name "tmp-*" \
-print0 | xargs -0 nix-store -qR | sort -u > "${WORKSPACE_TMP}"/store-paths.txt
""",
pure: false
)
nix.shell(
"""
nix-store --export < "${WORKSPACE_TMP}"/store-paths.txt | \\
ssh ${env.NIX_SSHOPTS} ${params.NIX_CACHE_USER}@${params.NIX_CACHE_HOST} ${env.NIX_STORE_CMD} --import
""", """,
pure: false pure: false
) )
@@ -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
-6
View File
@@ -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)
+2 -1
View File
@@ -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]}
@@ -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?))
@@ -182,22 +182,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,
@@ -490,25 +480,3 @@
(filter (fn [{:keys [tokens]}] (filter (fn [{:keys [tokens]}]
(some positive-balance-in-any-chain? tokens)) (some positive-balance-in-any-chain? tokens))
operable-account)))) operable-account))))
(defn calculate-max-safe-send-amount
"Calculates the max ETH that can be sent while reserving enough for gas fees.
- Ensures a minimum of 0.0001 ETH and a max of 0.01 ETH for gas.
- Uses 20% of the value as an estimated fee, clamped within this range.
- In Desktop it's 10% but after some more test, we found 20% is better option.
- Prevents sending the full balance to avoid transaction failures.
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)))
+40 -2
View File
@@ -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
+3 -92
View File
@@ -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?
@@ -587,82 +577,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"))
-30
View File
@@ -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))))
-10
View File
@@ -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)))
-15
View File
@@ -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))))
-16
View File
@@ -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)))))
@@ -43,7 +43,7 @@ class TestWalletCollectibles(MultipleSharedDeviceTestCase):
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)
collectibles = { collectibles = {
"BVL": {"quantity": 2, "BVL": {"quantity": 1,
"info": {"Account": "Account 1", "info": {"Account": "Account 1",
"Network": "Base", "Network": "Base",
"category": "Football Player", "category": "Football Player",
@@ -102,8 +102,8 @@ class TestWalletCollectibles(MultipleSharedDeviceTestCase):
self.wallet_view.collectibles_tab_on_select_token_view.click() self.wallet_view.collectibles_tab_on_select_token_view.click()
time.sleep(5) time.sleep(5)
self.wallet_view.get_collectible_element('BVL').click() self.wallet_view.get_collectible_element('BVL').click()
self.wallet_view.amount_input_increase_button.click() # self.wallet_view.amount_input_increase_button.click()
self.wallet_view.confirm_button.click() # self.wallet_view.confirm_button.click()
for text in [self.account_name, self.sender_short_address]: for text in [self.account_name, self.sender_short_address]:
if not self.wallet_view.from_data_container.get_child_element_by_text(text).is_element_displayed(): if not self.wallet_view.from_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(self.wallet_view, self.errors.append(self.wallet_view,
@@ -118,7 +118,7 @@ class TestWalletCollectibles(MultipleSharedDeviceTestCase):
data_to_check = { data_to_check = {
'Est. time': ' min', 'Est. time': ' min',
'Max fees': r"[$]\d+.\d+", 'Max fees': r"[$]\d+.\d+",
'Recipient gets': '2 ' 'Recipient gets': '1 '
} }
for key, expected_value in data_to_check.items(): for key, expected_value in data_to_check.items():
try: try:
Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 KiB

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB