feat(swap): set spending cap screen (#20727)
Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
parent
3b446963ef
commit
4b7c906df2
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
|
@ -28,6 +28,7 @@
|
||||||
{:type :spending-cap
|
{:type :spending-cap
|
||||||
:label "Spending Cap"
|
:label "Spending Cap"
|
||||||
:button-label "Edit"
|
:button-label "Edit"
|
||||||
|
:button-icon :i/options
|
||||||
:on-button-press on-button-press
|
:on-button-press on-button-press
|
||||||
:avatar-props {:image "image"}}])
|
:avatar-props {:image "image"}}])
|
||||||
(h/fire-event :press (h/get-by-text "Edit"))
|
(h/fire-event :press (h/get-by-text "Edit"))
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
:style (style/description blur? theme)}
|
:style (style/description blur? theme)}
|
||||||
description])]
|
description])]
|
||||||
(when (= type :account) [tiny-tag/view {:label tag-label}])
|
(when (= type :account) [tiny-tag/view {:label tag-label}])
|
||||||
(when (= type :spending-cap)
|
(when (and (= type :spending-cap) button-icon)
|
||||||
[button/button
|
[button/button
|
||||||
{:type :outline
|
{:type :outline
|
||||||
:size 24
|
:size 24
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
:gnosis (js/require "../resources/images/networks/Gnosis.png")
|
:gnosis (js/require "../resources/images/networks/Gnosis.png")
|
||||||
:hermez (js/require "../resources/images/networks/Hermez.png")
|
:hermez (js/require "../resources/images/networks/Hermez.png")
|
||||||
:optimism (js/require "../resources/images/networks/Optimism.png")
|
:optimism (js/require "../resources/images/networks/Optimism.png")
|
||||||
|
:paraswap (js/require "../resources/images/networks/Paraswap.png")
|
||||||
:polygon (js/require "../resources/images/networks/Polygon.png")
|
:polygon (js/require "../resources/images/networks/Polygon.png")
|
||||||
:scroll (js/require "../resources/images/networks/Scroll.png")
|
:scroll (js/require "../resources/images/networks/Scroll.png")
|
||||||
:taiko (js/require "../resources/images/networks/Taiko.png")
|
:taiko (js/require "../resources/images/networks/Taiko.png")
|
||||||
|
|
|
@ -579,5 +579,8 @@
|
||||||
(def ^:const max-recommended-slippage 5)
|
(def ^:const max-recommended-slippage 5)
|
||||||
(def ^:const max-slippage-decimal-places 2)
|
(def ^:const max-slippage-decimal-places 2)
|
||||||
(def ^:const swap-default-provider
|
(def ^:const swap-default-provider
|
||||||
{:name "Paraswap"
|
{:name :paraswap
|
||||||
|
:full-name "Paraswap"
|
||||||
|
:color :blue
|
||||||
|
:contract-address "0xdef171fe48cf0115b1d80b88dc8eab59176fee57"
|
||||||
:terms-and-conditions-url "https://files.paraswap.io/tos_v4.pdf"})
|
:terms-and-conditions-url "https://files.paraswap.io/tos_v4.pdf"})
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
(ns status-im.contexts.wallet.swap.set-spending-cap.style
|
||||||
|
(:require [quo.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(def container
|
||||||
|
{:flex 1
|
||||||
|
:margin-top -20})
|
||||||
|
|
||||||
|
(def detail-item
|
||||||
|
{:flex 1
|
||||||
|
:height 36
|
||||||
|
:background-color :transparent})
|
||||||
|
|
||||||
|
(def content-container
|
||||||
|
{:padding-top 12
|
||||||
|
:padding-horizontal 20
|
||||||
|
:padding-bottom 32})
|
||||||
|
|
||||||
|
(def title-container
|
||||||
|
{:margin-horizontal 4})
|
||||||
|
|
||||||
|
(def title-line-with-margin-top
|
||||||
|
{:flex-direction :row
|
||||||
|
:margin-top 4})
|
||||||
|
|
||||||
|
(def details-container
|
||||||
|
{:flex-direction :row
|
||||||
|
:justify-content :space-between
|
||||||
|
:height 52
|
||||||
|
:padding-top 7
|
||||||
|
:padding-horizontal 1
|
||||||
|
:margin-bottom 8})
|
||||||
|
|
||||||
|
(def summary-section-container
|
||||||
|
{:padding-horizontal 20
|
||||||
|
:padding-bottom 16})
|
||||||
|
|
||||||
|
(defn section-label
|
||||||
|
[theme]
|
||||||
|
{:margin-bottom 8
|
||||||
|
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
|
@ -0,0 +1,253 @@
|
||||||
|
(ns status-im.contexts.wallet.swap.set-spending-cap.view
|
||||||
|
(:require
|
||||||
|
[quo.core :as quo]
|
||||||
|
[quo.foundations.resources :as resources]
|
||||||
|
[quo.theme :as quo.theme]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||||
|
[status-im.common.standard-authentication.core :as standard-auth]
|
||||||
|
[status-im.contexts.wallet.common.utils.external-links :as external-links]
|
||||||
|
[status-im.contexts.wallet.swap.set-spending-cap.style :as style]
|
||||||
|
[utils.address :as address-utils]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
|
[utils.navigation :as navigation]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn- swap-title
|
||||||
|
[{:keys [pay-token-symbol pay-amount account provider]}]
|
||||||
|
[rn/view {:style style/content-container}
|
||||||
|
[rn/view {:style {:flex-direction :row}}
|
||||||
|
[quo/text
|
||||||
|
{:size :heading-1
|
||||||
|
:weight :semi-bold
|
||||||
|
:style style/title-container
|
||||||
|
:accessibility-label :set-spending-cap-of}
|
||||||
|
(i18n/label :t/set-spending-cap-of)]]
|
||||||
|
[rn/view {:style style/title-line-with-margin-top}
|
||||||
|
[quo/summary-tag
|
||||||
|
{:token pay-token-symbol
|
||||||
|
:label (str pay-amount " " pay-token-symbol)
|
||||||
|
:type :token}]
|
||||||
|
[quo/text
|
||||||
|
{:size :heading-1
|
||||||
|
:weight :semi-bold
|
||||||
|
:style style/title-container
|
||||||
|
:accessibility-label :for}
|
||||||
|
(i18n/label :t/for)]]
|
||||||
|
[rn/view {:style style/title-line-with-margin-top}
|
||||||
|
[quo/summary-tag
|
||||||
|
{:label (:full-name provider)
|
||||||
|
:type :network
|
||||||
|
:image-source (resources/get-network (:name provider))
|
||||||
|
:customization-color (:color provider)}]
|
||||||
|
[quo/text
|
||||||
|
{:size :heading-1
|
||||||
|
:weight :semi-bold
|
||||||
|
:style style/title-container
|
||||||
|
:accessibility-label :on}
|
||||||
|
(i18n/label :t/on)]]
|
||||||
|
[rn/view {:style style/title-line-with-margin-top}
|
||||||
|
[quo/summary-tag
|
||||||
|
{:label (:name account)
|
||||||
|
:type :account
|
||||||
|
:emoji (:emoji account)
|
||||||
|
:customization-color (:color account)}]]])
|
||||||
|
|
||||||
|
(defn- spending-cap-section
|
||||||
|
[{:keys [theme amount token-symbol]}]
|
||||||
|
[rn/view {:style style/summary-section-container}
|
||||||
|
[quo/text
|
||||||
|
{:size :paragraph-2
|
||||||
|
:weight :medium
|
||||||
|
:style (style/section-label theme)
|
||||||
|
:accessibility-label :spending-cap-label}
|
||||||
|
(i18n/label :t/spending-cap)]
|
||||||
|
[quo/approval-info
|
||||||
|
{:type :spending-cap
|
||||||
|
:unlimited-icon? false
|
||||||
|
:label (str amount " " token-symbol)
|
||||||
|
:avatar-props {:token token-symbol}}]])
|
||||||
|
|
||||||
|
(defn- account-section
|
||||||
|
[{:keys [theme account pay-token-symbol pay-token-amount]}]
|
||||||
|
[rn/view {:style style/summary-section-container}
|
||||||
|
[quo/text
|
||||||
|
{:size :paragraph-2
|
||||||
|
:weight :medium
|
||||||
|
:style (style/section-label theme)
|
||||||
|
:accessibility-label :account-label}
|
||||||
|
(i18n/label :t/account)]
|
||||||
|
[quo/approval-info
|
||||||
|
{:type :account
|
||||||
|
:unlimited-icon? false
|
||||||
|
:label (:name account)
|
||||||
|
:description (address-utils/get-short-wallet-address (:address account))
|
||||||
|
:tag-label (str pay-token-amount " " pay-token-symbol)
|
||||||
|
:avatar-props {:emoji (:emoji account)
|
||||||
|
:customization-color (:color account)}}]])
|
||||||
|
|
||||||
|
(defn- on-option-press
|
||||||
|
[{:keys [chain-id contract-address]}]
|
||||||
|
(rf/dispatch
|
||||||
|
[:show-bottom-sheet
|
||||||
|
{:content (fn []
|
||||||
|
[quo/action-drawer
|
||||||
|
[[{:icon :i/link
|
||||||
|
:accessibility-label :view-on-etherscan
|
||||||
|
:on-press (fn []
|
||||||
|
(rf/dispatch
|
||||||
|
[:wallet/navigate-to-chain-explorer-from-bottom-sheet
|
||||||
|
(external-links/get-explorer-url-by-chain-id chain-id)
|
||||||
|
contract-address]))
|
||||||
|
:label (i18n/label :t/view-on-eth)
|
||||||
|
:right-icon :i/external}]]])}]))
|
||||||
|
|
||||||
|
(defn- token-section
|
||||||
|
[{:keys [theme token-address token-symbol network-chain-id]}]
|
||||||
|
[rn/view {:style style/summary-section-container}
|
||||||
|
[quo/text
|
||||||
|
{:size :paragraph-2
|
||||||
|
:weight :medium
|
||||||
|
:style (style/section-label theme)
|
||||||
|
:accessibility-label :token-label}
|
||||||
|
(i18n/label :t/token)]
|
||||||
|
[quo/approval-info
|
||||||
|
{:type :token-contract
|
||||||
|
:option-icon :i/options
|
||||||
|
:on-option-press #(on-option-press {:chain-id network-chain-id
|
||||||
|
:contract-address token-address})
|
||||||
|
:unlimited-icon? false
|
||||||
|
:label token-symbol
|
||||||
|
:description (address-utils/get-short-wallet-address token-address)
|
||||||
|
:avatar-props {:token token-symbol}}]])
|
||||||
|
|
||||||
|
(defn- spender-contract-section
|
||||||
|
[{:keys [theme provider network-chain-id]}]
|
||||||
|
[rn/view {:style style/summary-section-container}
|
||||||
|
[quo/text
|
||||||
|
{:size :paragraph-2
|
||||||
|
:weight :medium
|
||||||
|
:style (style/section-label theme)
|
||||||
|
:accessibility-label :spender-contract-label}
|
||||||
|
(i18n/label :t/spender-contract)]
|
||||||
|
[quo/approval-info
|
||||||
|
{:type :token-contract
|
||||||
|
:option-icon :i/options
|
||||||
|
:on-option-press #(on-option-press {:chain-id network-chain-id
|
||||||
|
:contract-address (:contract-address provider)})
|
||||||
|
:unlimited-icon? false
|
||||||
|
:label (:full-name provider)
|
||||||
|
:description (address-utils/get-short-wallet-address (:contract-address provider))
|
||||||
|
:avatar-props {:image (resources/get-network (:name provider))}}]])
|
||||||
|
|
||||||
|
(defn- data-item
|
||||||
|
[{:keys [network-image title subtitle size loading?]}]
|
||||||
|
[quo/data-item
|
||||||
|
{:container-style style/detail-item
|
||||||
|
:blur? false
|
||||||
|
:card? false
|
||||||
|
:network-image network-image
|
||||||
|
:subtitle-type (if network-image :network :default)
|
||||||
|
:status (if loading? :loading :default)
|
||||||
|
:title title
|
||||||
|
:subtitle subtitle
|
||||||
|
:size size}])
|
||||||
|
|
||||||
|
(defn- transaction-details
|
||||||
|
[{:keys [estimated-time-min max-fees network loading-fees?]}]
|
||||||
|
[rn/view {:style style/details-container}
|
||||||
|
[:<>
|
||||||
|
[data-item
|
||||||
|
{:title (i18n/label :t/network)
|
||||||
|
:subtitle (:full-name network)
|
||||||
|
:network-image (:source network)}]
|
||||||
|
[data-item
|
||||||
|
{:title (i18n/label :t/est-time)
|
||||||
|
:subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time-min)})}]
|
||||||
|
[data-item
|
||||||
|
{:title (i18n/label :t/max-fees)
|
||||||
|
:subtitle max-fees
|
||||||
|
:loading? loading-fees?
|
||||||
|
:size :small}]]])
|
||||||
|
|
||||||
|
(defn footer
|
||||||
|
[{:keys [estimated-time-min native-currency-symbol network theme account-color loading-fees?]}]
|
||||||
|
(let [native-token (when native-currency-symbol
|
||||||
|
(rf/sub [:wallet/token-by-symbol
|
||||||
|
native-currency-symbol]))
|
||||||
|
fee-formatted (rf/sub [:wallet/wallet-send-fee-fiat-formatted
|
||||||
|
native-token])
|
||||||
|
on-auth-success (rn/use-callback #(js/alert "Not implemented yet"))]
|
||||||
|
[rn/view {:style {:margin-bottom -10}}
|
||||||
|
[transaction-details
|
||||||
|
{:estimated-time-min estimated-time-min
|
||||||
|
:max-fees fee-formatted
|
||||||
|
:network network
|
||||||
|
:loading-fees? loading-fees?
|
||||||
|
:theme theme}]
|
||||||
|
[standard-auth/slide-button
|
||||||
|
{:size :size-48
|
||||||
|
:track-text (i18n/label :t/slide-to-swap)
|
||||||
|
:container-style {:z-index 2}
|
||||||
|
:customization-color account-color
|
||||||
|
:disabled? loading-fees?
|
||||||
|
:on-auth-success on-auth-success
|
||||||
|
:auth-button-label (i18n/label :t/confirm)}]]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [theme (quo.theme/use-theme)
|
||||||
|
swap-transaction-data (rf/sub [:wallet/swap])
|
||||||
|
{:keys [asset-to-pay network pay-amount
|
||||||
|
providers swap-proposal
|
||||||
|
loading-fees?]} swap-transaction-data
|
||||||
|
estimated-time-min (:estimated-time swap-proposal)
|
||||||
|
pay-token-symbol (:symbol asset-to-pay)
|
||||||
|
pay-token-address (:address asset-to-pay)
|
||||||
|
native-currency-symbol (get-in swap-proposal [:from :native-currency-symbol])
|
||||||
|
account (rf/sub [:wallet/current-viewing-account])
|
||||||
|
account-color (:color account)
|
||||||
|
provider (first providers)]
|
||||||
|
[rn/view {:style style/container}
|
||||||
|
[floating-button-page/view
|
||||||
|
{:footer-container-padding 0
|
||||||
|
:header [quo/page-nav
|
||||||
|
{:icon-name :i/close
|
||||||
|
:on-press navigation/navigate-back
|
||||||
|
:margin-top 8
|
||||||
|
:background :blur
|
||||||
|
:accessibility-label :top-bar}]
|
||||||
|
:footer [footer
|
||||||
|
{:estimated-time-min estimated-time-min
|
||||||
|
:native-currency-symbol native-currency-symbol
|
||||||
|
:network network
|
||||||
|
:account-color account-color
|
||||||
|
:provider provider
|
||||||
|
:loading-fees? loading-fees?
|
||||||
|
:theme theme}]
|
||||||
|
:gradient-cover? true
|
||||||
|
:customization-color account-color}
|
||||||
|
[:<>
|
||||||
|
[swap-title
|
||||||
|
{:pay-token-symbol pay-token-symbol
|
||||||
|
:pay-amount pay-amount
|
||||||
|
:account account
|
||||||
|
:provider provider}]
|
||||||
|
[spending-cap-section
|
||||||
|
{:token-symbol pay-token-symbol
|
||||||
|
:amount pay-amount
|
||||||
|
:theme theme}]
|
||||||
|
[account-section
|
||||||
|
{:account account
|
||||||
|
:pay-token-symbol pay-token-symbol
|
||||||
|
:pay-token-amount pay-amount
|
||||||
|
:theme theme}]
|
||||||
|
[token-section
|
||||||
|
{:token-symbol pay-token-symbol
|
||||||
|
:token-address pay-token-address
|
||||||
|
:network-chain-id (:chain-id network)
|
||||||
|
:theme theme}]
|
||||||
|
[spender-contract-section
|
||||||
|
{:provider provider
|
||||||
|
:network-chain-id (:chain-id network)
|
||||||
|
:theme theme}]]]]))
|
|
@ -16,4 +16,7 @@
|
||||||
[quo/button
|
[quo/button
|
||||||
{:on-press #(rf/dispatch [:navigate-to-within-stack
|
{:on-press #(rf/dispatch [:navigate-to-within-stack
|
||||||
[:screen/wallet.swap-confirmation :screen/wallet.swap-propasal]])}
|
[:screen/wallet.swap-confirmation :screen/wallet.swap-propasal]])}
|
||||||
"Swap confirmation"]]))
|
"Swap confirmation"]
|
||||||
|
[quo/button
|
||||||
|
{:on-press #(rf/dispatch [:open-modal :screen/wallet.swap-set-spending-cap])}
|
||||||
|
"Set spending cap"]]))
|
||||||
|
|
|
@ -118,6 +118,7 @@
|
||||||
[status-im.contexts.wallet.send.transaction-confirmation.view :as wallet-transaction-confirmation]
|
[status-im.contexts.wallet.send.transaction-confirmation.view :as wallet-transaction-confirmation]
|
||||||
[status-im.contexts.wallet.send.transaction-progress.view :as wallet-transaction-progress]
|
[status-im.contexts.wallet.send.transaction-progress.view :as wallet-transaction-progress]
|
||||||
[status-im.contexts.wallet.swap.select-asset-to-pay.view :as wallet-swap-select-asset-to-pay]
|
[status-im.contexts.wallet.swap.select-asset-to-pay.view :as wallet-swap-select-asset-to-pay]
|
||||||
|
[status-im.contexts.wallet.swap.set-spending-cap.view :as wallet-swap-set-spending-cap]
|
||||||
[status-im.contexts.wallet.swap.swap-confirmation.view :as wallet-swap-confirmation]
|
[status-im.contexts.wallet.swap.swap-confirmation.view :as wallet-swap-confirmation]
|
||||||
[status-im.contexts.wallet.swap.swap-proposal.view :as wallet-swap-propasal]
|
[status-im.contexts.wallet.swap.swap-proposal.view :as wallet-swap-propasal]
|
||||||
[status-im.contexts.wallet.wallet-connect.modals.send-transaction.view :as
|
[status-im.contexts.wallet.wallet-connect.modals.send-transaction.view :as
|
||||||
|
@ -526,6 +527,10 @@
|
||||||
:options {:modalPresentationStyle :overCurrentContext}
|
:options {:modalPresentationStyle :overCurrentContext}
|
||||||
:component wallet-swap-confirmation/view}
|
:component wallet-swap-confirmation/view}
|
||||||
|
|
||||||
|
{:name :screen/wallet.swap-set-spending-cap
|
||||||
|
:options {:sheet? true}
|
||||||
|
:component wallet-swap-set-spending-cap/view}
|
||||||
|
|
||||||
{:name :scan-profile-qr-code
|
{:name :scan-profile-qr-code
|
||||||
:options (merge
|
:options (merge
|
||||||
options/dark-screen
|
options/dark-screen
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"accepted": "Accepted",
|
"accepted": "Accepted",
|
||||||
"access-existing-keys": "Access existing keys",
|
"access-existing-keys": "Access existing keys",
|
||||||
"access-key": "Access key",
|
"access-key": "Access key",
|
||||||
|
"account": "Account",
|
||||||
"account-added": "Account added",
|
"account-added": "Account added",
|
||||||
"account-color": "Account color",
|
"account-color": "Account color",
|
||||||
"account-content": "You can compare accounts in Status to bank accounts. Like a bank account, an account typically has an address and a balance; You use this account to transact on Ethereum. You can have multiple accounts in your wallet. All accessed by unlocking Status.",
|
"account-content": "You can compare accounts in Status to bank accounts. Like a bank account, an account typically has an address and a balance; You use this account to transact on Ethereum. You can have multiple accounts in your wallet. All accessed by unlocking Status.",
|
||||||
|
@ -1016,6 +1017,7 @@
|
||||||
"fleet-settings": "Fleet settings",
|
"fleet-settings": "Fleet settings",
|
||||||
"follow": "Follow",
|
"follow": "Follow",
|
||||||
"follow-your-interests": "Jump into a public chat and meet new people",
|
"follow-your-interests": "Jump into a public chat and meet new people",
|
||||||
|
"for": "for",
|
||||||
"for-airdrops": "For airdrops",
|
"for-airdrops": "For airdrops",
|
||||||
"forgot-password": "Forgot password?",
|
"forgot-password": "Forgot password?",
|
||||||
"forgot-your-password-info-create-new-password": "Create a new password",
|
"forgot-your-password-info-create-new-password": "Create a new password",
|
||||||
|
@ -2189,6 +2191,7 @@
|
||||||
"set-dapp-access-permissions": "Set DApp access permissions",
|
"set-dapp-access-permissions": "Set DApp access permissions",
|
||||||
"set-max": "Set max",
|
"set-max": "Set max",
|
||||||
"set-nickname-toast": "You have renamed {{primary-name}} as {{nickname}}",
|
"set-nickname-toast": "You have renamed {{primary-name}} as {{nickname}}",
|
||||||
|
"set-spending-cap-of": "Set spending cap of",
|
||||||
"set-up-sync": "Set up sync",
|
"set-up-sync": "Set up sync",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"setup-group-chat": "Setup group chat",
|
"setup-group-chat": "Setup group chat",
|
||||||
|
@ -2285,6 +2288,8 @@
|
||||||
"specify-network-id": "Specify network id",
|
"specify-network-id": "Specify network id",
|
||||||
"specify-server-public-key": "Enter server public key",
|
"specify-server-public-key": "Enter server public key",
|
||||||
"specify-symbol": "Specify a symbol",
|
"specify-symbol": "Specify a symbol",
|
||||||
|
"spender-contract": "Spender contract",
|
||||||
|
"spending-cap": "Spending cap",
|
||||||
"start-chat": "Start chat",
|
"start-chat": "Start chat",
|
||||||
"start-conversation": "Start conversation",
|
"start-conversation": "Start conversation",
|
||||||
"start-group-chat": "Start group chat",
|
"start-group-chat": "Start group chat",
|
||||||
|
|
Loading…
Reference in New Issue