From 1666b2aee0c54eb5f399cded12b9419457b18cab Mon Sep 17 00:00:00 2001
From: Josh Leonard <30185185+josheleonard@users.noreply.github.com>
Date: Mon, 30 Jan 2023 13:29:08 -0700
Subject: [PATCH] Fix allow gas price value below current base fee (#16810)
* chore: rename edit-gas component files; re-export
* fix: allow gas value below base fee
---
.../browser/brave_wallet_constants.h | 2 +
.../svg-icons/warning-triangle-filled.svg | 5 +
.../brave_wallet_ui/common/async/handlers.ts | 4 +-
.../confirm-transaction-panel/common/gas.tsx | 15 +-
.../edit-gas/{style.ts => edit-gas.styles.ts} | 23 +-
.../edit-gas/{index.tsx => edit-gas.tsx} | 292 +++++++++++-------
.../components/extension/index.ts | 2 +-
.../extension/shared-panel-styles.ts | 12 +-
.../components/extension/sign-panel/index.tsx | 6 +-
.../sign-panel/sign-transaction-panel.tsx | 6 +-
.../components/extension/sign-panel/style.ts | 8 +-
.../leo/alert-inline/alert-inline.stories.tsx | 19 ++
.../leo/alert-inline/alert-inline.style.ts | 43 +++
.../leo/alert-inline/alert-inline.tsx | 62 ++++
.../components/leo/alert-inline/leo-colors.ts | 18 ++
.../components/shared/style.tsx | 46 +++
components/brave_wallet_ui/constants/types.ts | 2 +
components/brave_wallet_ui/stories/locale.ts | 3 +
components/resources/wallet_strings.grdp | 1 +
19 files changed, 424 insertions(+), 145 deletions(-)
create mode 100644 components/brave_wallet_ui/assets/svg-icons/warning-triangle-filled.svg
rename components/brave_wallet_ui/components/extension/edit-gas/{style.ts => edit-gas.styles.ts} (90%)
rename components/brave_wallet_ui/components/extension/edit-gas/{index.tsx => edit-gas.tsx} (68%)
create mode 100644 components/brave_wallet_ui/components/leo/alert-inline/alert-inline.stories.tsx
create mode 100644 components/brave_wallet_ui/components/leo/alert-inline/alert-inline.style.ts
create mode 100644 components/brave_wallet_ui/components/leo/alert-inline/alert-inline.tsx
create mode 100644 components/brave_wallet_ui/components/leo/alert-inline/leo-colors.ts
diff --git a/components/brave_wallet/browser/brave_wallet_constants.h b/components/brave_wallet/browser/brave_wallet_constants.h
index bc5ebfade623..be34fdc503c1 100644
--- a/components/brave_wallet/browser/brave_wallet_constants.h
+++ b/components/brave_wallet/browser/brave_wallet_constants.h
@@ -42,6 +42,8 @@ constexpr char kTransakURL[] = "https://global.transak.com/";
constexpr char kTransakApiKey[] = "985d14f0-4cf5-4a4c-8917-78107620d3b7";
constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"braveWalletGasFeeLimitLowerThanBaseFeeWarning",
+ IDS_BRAVE_WALLET_GAS_FEE_LIMIT_LOWER_THAN_BASE_FEE_WARNING},
{"braveWalletTokenMintAddress", IDS_BRAVE_WALLET_TOKEN_MINT_ADDRESS},
{"braveWalletActivity", IDS_BRAVE_WALLET_ACTIVITY},
{"braveWalletTokenDecimalsIsRequiredError",
diff --git a/components/brave_wallet_ui/assets/svg-icons/warning-triangle-filled.svg b/components/brave_wallet_ui/assets/svg-icons/warning-triangle-filled.svg
new file mode 100644
index 000000000000..fc1bb1f46096
--- /dev/null
+++ b/components/brave_wallet_ui/assets/svg-icons/warning-triangle-filled.svg
@@ -0,0 +1,5 @@
+
diff --git a/components/brave_wallet_ui/common/async/handlers.ts b/components/brave_wallet_ui/common/async/handlers.ts
index 6e120414c780..2c3c7a06fe3e 100644
--- a/components/brave_wallet_ui/common/async/handlers.ts
+++ b/components/brave_wallet_ui/common/async/handlers.ts
@@ -553,8 +553,8 @@ handler.on(WalletActions.updateUnapprovedTransactionGasFields.type, async (store
if (isEIP1559) {
const result = await apiProxy.ethTxManagerProxy.setGasFeeAndLimitForUnapprovedTransaction(
payload.txMetaId,
- payload.maxPriorityFeePerGas || '',
- payload.maxFeePerGas || '',
+ payload.maxPriorityFeePerGas || '0x0',
+ payload.maxFeePerGas || '0x0',
payload.gasLimit
)
diff --git a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx
index da1407f86d1b..763de4e722bd 100644
--- a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx
+++ b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx
@@ -4,11 +4,16 @@
// you can obtain one at https://mozilla.org/MPL/2.0/.
import * as React from 'react'
+import { useSelector } from 'react-redux'
-import EditGas, { MaxPriorityPanels } from '../../edit-gas'
+// hooks
import { usePendingTransactions } from '../../../../common/hooks/use-pending-transaction'
-import { useSelector } from 'react-redux'
-import { WalletState } from '../../../../constants/types'
+
+// components
+import EditGas, { MaxPriorityPanels } from '../../edit-gas/edit-gas'
+
+// selectors
+import { WalletSelectors } from '../../../../common/selectors'
interface Props {
onCancel: () => void
@@ -18,8 +23,8 @@ export function EditPendingTransactionGas (props: Props) {
const { onCancel } = props
// redux
- const { selectedPendingTransaction: transactionInfo } = useSelector(
- ({ wallet }: { wallet: WalletState }) => wallet
+ const transactionInfo = useSelector(
+ WalletSelectors.selectedPendingTransaction
)
const [suggestedSliderStep, setSuggestedSliderStep] = React.useState('1')
diff --git a/components/brave_wallet_ui/components/extension/edit-gas/style.ts b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.styles.ts
similarity index 90%
rename from components/brave_wallet_ui/components/extension/edit-gas/style.ts
rename to components/brave_wallet_ui/components/extension/edit-gas/edit-gas.styles.ts
index 5f7c6d3a4b41..bb233e4fc7f4 100644
--- a/components/brave_wallet_ui/components/extension/edit-gas/style.ts
+++ b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.styles.ts
@@ -1,8 +1,10 @@
// Copyright (c) 2021 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// you can obtain one at https://mozilla.org/MPL/2.0/.
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
import styled from 'styled-components'
+import { LeoColors } from '../../leo/alert-inline/leo-colors'
export const StyledWrapper = styled.div`
display: flex;
@@ -12,6 +14,7 @@ export const StyledWrapper = styled.div`
width: 100%;
height: 100%;
padding: 5px 15px 15px 15px;
+ overflow-y: auto;
`
export const FormColumn = styled.div`
@@ -41,7 +44,12 @@ export const Input = styled.input<{
background-image: none;
background-color: ${(p) => p.theme.color.background02};
box-shadow: none;
- border: ${(p) => `1px solid ${p.theme.color.interactive08}`};
+ border-style: solid;
+ border-width: 1px;
+ border-color: ${(p) =>
+ p.hasError
+ ? LeoColors['light.system.feedback.error.icon']
+ : p.theme.color.interactive08};
border-radius: 4px;
font-family: Poppins;
font-style: normal;
@@ -50,9 +58,7 @@ export const Input = styled.input<{
letter-spacing: 0.01em;
padding: 10px;
margin-bottom: 8px;
- color: ${(p) => p.hasError
- ? p.theme.color.errorText
- : p.theme.color.text01};
+ color: ${(p) => p.theme.color.text01};
::placeholder {
font-family: Poppins;
font-style: normal;
@@ -72,6 +78,12 @@ export const Input = styled.input<{
-webkit-appearance: none;
margin: 0;
}
+ @media (prefers-color-scheme: dark) {
+ border-color: ${(p) =>
+ p.hasError
+ ? LeoColors['light.system.feedback.error.icon']
+ : p.theme.color.interactive08};
+ }
`
export const ButtonRow = styled.div`
@@ -125,7 +137,6 @@ export const MaximumFeeRow = styled.div`
justify-content: space-between;
flex-direction: row;
width: 100%;
- margin-bottom: 8px;
`
export const SliderWrapper = styled.div`
diff --git a/components/brave_wallet_ui/components/extension/edit-gas/index.tsx b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx
similarity index 68%
rename from components/brave_wallet_ui/components/extension/edit-gas/index.tsx
rename to components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx
index 8121abb619ae..4bd9b6b15d07 100644
--- a/components/brave_wallet_ui/components/extension/edit-gas/index.tsx
+++ b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx
@@ -8,15 +8,15 @@ import { getLocale } from '../../../../common/locale'
import { BraveWallet, SerializableTransactionInfo } from '../../../constants/types'
import { UpdateUnapprovedTransactionGasFieldsType } from '../../../common/constants/action_types'
-import { NavButton, Panel } from '../'
+import { NavButton, Panel } from '..'
// Utils
import Amount from '../../../utils/amount'
// Hooks
import { useTransactionFeesParser } from '../../../common/hooks'
-
// Styled Components
+import { ErrorText, Row } from '../../shared/style'
import {
StyledWrapper,
FormColumn,
@@ -34,15 +34,15 @@ import {
SliderWrapper,
SliderValue,
WarningText
-} from './style'
-import { ErrorText } from '../../shared/style'
+} from './edit-gas.styles'
+import AlertInline from '../../leo/alert-inline/alert-inline'
export enum MaxPriorityPanels {
setSuggested = 0,
setCustom = 1
}
-export interface Props {
+interface Props {
onCancel: () => void
networkSpotPrice: string
transactionInfo: SerializableTransactionInfo
@@ -56,24 +56,24 @@ export interface Props {
setMaxPriorityPanel: (value: MaxPriorityPanels) => void
}
-const EditGas = (props: Props) => {
- const {
- onCancel,
- networkSpotPrice,
- selectedNetwork,
- transactionInfo,
- baseFeePerGas,
- suggestedMaxPriorityFeeChoices,
- suggestedSliderStep,
- maxPriorityPanel,
- updateUnapprovedTransactionGasFields,
- setSuggestedSliderStep,
- setMaxPriorityPanel
- } = props
+export const EditGas = ({
+ onCancel,
+ networkSpotPrice,
+ selectedNetwork,
+ transactionInfo,
+ baseFeePerGas,
+ suggestedMaxPriorityFeeChoices,
+ suggestedSliderStep,
+ maxPriorityPanel,
+ updateUnapprovedTransactionGasFields,
+ setSuggestedSliderStep,
+ setMaxPriorityPanel
+}: Props) => {
const parseTransactionFees = useTransactionFeesParser(selectedNetwork, networkSpotPrice)
const transactionFees = parseTransactionFees(transactionInfo)
const { isEIP1559Transaction } = transactionFees
+ // state
const [suggestedMaxPriorityFee, setSuggestedMaxPriorityFee] = React.useState(suggestedMaxPriorityFeeChoices[1])
const [gasLimit, setGasLimit] = React.useState(transactionFees.gasLimit)
const [gasPrice, setGasPrice] = React.useState(
@@ -92,21 +92,7 @@ const EditGas = (props: Props) => {
.format()
)
- React.useEffect(
- () => {
- const maxPriorityFeePerGasWei = new Amount(maxPriorityFeePerGas)
- .multiplyByDecimals(9) // GWei-per-gas → Wei conversion
-
- const maxFeePerGasWeiValue = new Amount(baseFeePerGas)
- .plus(maxPriorityFeePerGasWei)
-
- setMaxFeePerGas(maxFeePerGasWeiValue
- .divideByDecimals(9) // Wei-per-gas → GWei-per-gas conversion
- .format())
- },
- [baseFeePerGas]
- )
-
+ // methods
const handleGasPriceInputChanged = (event: React.ChangeEvent) => {
setGasPrice(event.target.value)
}
@@ -168,46 +154,6 @@ const EditGas = (props: Props) => {
setMaxFeePerGas(computedMaxFeePerGasGWei)
}
- const showSuggestedMaxPriorityPanel = isEIP1559Transaction && maxPriorityPanel === MaxPriorityPanels.setSuggested
- const showCustomMaxPriorityPanel = isEIP1559Transaction && maxPriorityPanel === MaxPriorityPanels.setCustom
- const suggestedEIP1559GasFee = showSuggestedMaxPriorityPanel
- ? new Amount(baseFeePerGas)
- .plus(suggestedMaxPriorityFee)
- .times(gasLimit) // Wei-per-gas → Wei conversion
- .divideByDecimals(selectedNetwork.decimals) // Wei → ETH conversion
- .format(6)
- : undefined
-
- const suggestedEIP1559FiatGasFee = suggestedEIP1559GasFee && new Amount(suggestedEIP1559GasFee)
- .times(networkSpotPrice)
- .formatAsFiat()
-
- const customEIP1559GasFee = showCustomMaxPriorityPanel
- ? new Amount(maxFeePerGas)
- .multiplyByDecimals(9) // GWei-per-gas → Wei-per-gas conversion
- .times(gasLimit) // Wei-per-gas → Wei
- .divideByDecimals(selectedNetwork.decimals) // Wei → ETH conversion
- .format(6)
- : undefined
- const customEIP1559FiatGasFee = customEIP1559GasFee && new Amount(customEIP1559GasFee)
- .times(networkSpotPrice)
- .formatAsFiat()
-
- const gasLimitComponent = (
- <>
- {getLocale('braveWalletEditGasLimit')}
-
- {gasLimit === '0' && {getLocale('braveWalletEditGasLimitError')}}
- >
- )
-
const onSave = () => {
if (!isEIP1559Transaction) {
updateUnapprovedTransactionGasFields({
@@ -250,6 +196,52 @@ const EditGas = (props: Props) => {
onCancel()
}
+ // computed & memos
+ const showSuggestedMaxPriorityPanel = isEIP1559Transaction && maxPriorityPanel === MaxPriorityPanels.setSuggested
+ const showCustomMaxPriorityPanel = isEIP1559Transaction && maxPriorityPanel === MaxPriorityPanels.setCustom
+ const suggestedEIP1559GasFee = showSuggestedMaxPriorityPanel
+ ? new Amount(baseFeePerGas)
+ .plus(suggestedMaxPriorityFee)
+ .times(gasLimit) // Wei-per-gas → Wei conversion
+ .divideByDecimals(selectedNetwork.decimals) // Wei → ETH conversion
+ .format(6)
+ : undefined
+
+ const suggestedEIP1559FiatGasFee = suggestedEIP1559GasFee && new Amount(suggestedEIP1559GasFee)
+ .times(networkSpotPrice)
+ .formatAsFiat()
+
+ const customEIP1559GasFee = showCustomMaxPriorityPanel
+ ? new Amount(maxFeePerGas)
+ .multiplyByDecimals(9) // GWei-per-gas → Wei-per-gas conversion
+ .times(gasLimit) // Wei-per-gas → Wei
+ .divideByDecimals(selectedNetwork.decimals) // Wei → ETH conversion
+ .format(6)
+ : undefined
+ const customEIP1559FiatGasFee = customEIP1559GasFee && new Amount(customEIP1559GasFee)
+ .times(networkSpotPrice)
+ .formatAsFiat()
+
+ const gasLimitComponent = React.useMemo(
+ () => (
+ <>
+ {getLocale('braveWalletEditGasLimit')}
+
+ {gasLimit === '0' && (
+ {getLocale('braveWalletEditGasLimitError')}
+ )}
+ >
+ ),
+ [gasLimit, handleGasLimitInputChanged]
+ )
+
const isZeroGasPrice = React.useMemo(() => {
return (
!isEIP1559Transaction &&
@@ -273,8 +265,10 @@ const EditGas = (props: Props) => {
return true
}
- if (!isEIP1559Transaction &&
- new Amount(gasPrice).multiplyByDecimals(9).isNegative()) {
+ if (
+ !isEIP1559Transaction &&
+ new Amount(gasPrice).multiplyByDecimals(9).isNegative()
+ ) {
return true
}
@@ -282,71 +276,127 @@ const EditGas = (props: Props) => {
return true
}
- if (isEIP1559Transaction &&
- new Amount(maxFeePerGas).multiplyByDecimals(9).lte(baseFeePerGas)
- ) {
- return true
- }
-
- return isEIP1559Transaction &&
+ return (
+ isEIP1559Transaction &&
new Amount(maxPriorityFeePerGas).multiplyByDecimals(9).isNegative()
- }, [gasLimit, gasPrice, maxPriorityFeePerGas, maxFeePerGas])
+ )
+ }, [
+ gasLimit,
+ isEIP1559Transaction,
+ gasPrice,
+ maxFeePerGas,
+ baseFeePerGas,
+ maxPriorityFeePerGas
+ ])
+
+ const isCustomGasBelowBaseFee = React.useMemo(
+ () =>
+ isEIP1559Transaction &&
+ new Amount(maxFeePerGas).multiplyByDecimals(9).lt(baseFeePerGas),
+ [isEIP1559Transaction, maxFeePerGas, baseFeePerGas]
+ )
+
+ // effects
+ React.useEffect(() => {
+ const maxPriorityFeePerGasWei = new Amount(
+ maxPriorityFeePerGas
+ ).multiplyByDecimals(9) // GWei-per-gas → Wei conversion
+ const maxFeePerGasWeiValue = new Amount(baseFeePerGas).plus(
+ maxPriorityFeePerGasWei
+ )
+
+ setMaxFeePerGas(
+ maxFeePerGasWeiValue
+ .divideByDecimals(9) // Wei-per-gas → GWei-per-gas conversion
+ .format()
+ )
+ }, [maxPriorityFeePerGas, baseFeePerGas])
+
+ // render
return (
- {isEIP1559Transaction &&
- {getLocale('braveWalletEditGasDescription')}
- }
- {showCustomMaxPriorityPanel &&
+ {isEIP1559Transaction && (
+
+ {getLocale('braveWalletEditGasDescription')}
+
+ )}
+ {showCustomMaxPriorityPanel && (
- {getLocale('braveWalletEditGasBaseFee')}
- {
- `${new Amount(baseFeePerGas).divideByDecimals(9).format()}
- ${getLocale('braveWalletEditGasGwei')}`
- }
+ {getLocale('braveWalletEditGasBaseFee')}
+
+
+ {`${new Amount(baseFeePerGas).divideByDecimals(9).format()}
+ ${getLocale('braveWalletEditGasGwei')}`}
{gasLimitComponent}
- {getLocale('braveWalletEditGasPerTipLimit')}
+
+ {getLocale('braveWalletEditGasPerTipLimit')}
+
- {getLocale('braveWalletEditGasPerPriceLimit')}
+ {/* Gas-Per-Price Limit */}
+
+ {getLocale('braveWalletEditGasPerPriceLimit')}
+
- {getLocale('braveWalletEditGasMaximumFee')}
- ~${customEIP1559FiatGasFee} USD (${customEIP1559GasFee} {selectedNetwork.symbol})
+ {getLocale('braveWalletEditGasMaximumFee')}
+
+
+ ~${customEIP1559FiatGasFee} USD (${customEIP1559GasFee}{' '}
+ {selectedNetwork.symbol})
+ {isCustomGasBelowBaseFee && (
+
+
+
+ )}
- }
+ )}
- {showSuggestedMaxPriorityPanel &&
+ {showSuggestedMaxPriorityPanel && (
{getLocale('braveWalletEditGasMaxFee')}:
- ~${suggestedEIP1559FiatGasFee}
- {' '}USD ({suggestedEIP1559GasFee}
- {' '}{selectedNetwork.symbol})
+ ~${suggestedEIP1559FiatGasFee} USD ({suggestedEIP1559GasFee}{' '}
+ {selectedNetwork.symbol})
+
{
/>
{getLocale('braveWalletEditGasLow')}
- {getLocale('braveWalletEditGasOptimal')}
+
+ {getLocale('braveWalletEditGasOptimal')}
+
{getLocale('braveWalletEditGasHigh')}
- }
+ )}
- {!isEIP1559Transaction &&
+ {!isEIP1559Transaction && (
{gasLimitComponent}
- {getLocale('braveWalletEditGasPerGasPrice')}
+
+ {getLocale('braveWalletEditGasPerGasPrice')}
+
{
/>
{isZeroGasPrice && (
- {getLocale('braveWalletEditGasZeroGasPriceWarning')}
+
+ {getLocale('braveWalletEditGasZeroGasPriceWarning')}
+
)}
- }
+ )}
+
{
+ return
+}
+
+_AlertInline.story = {
+ name: 'Inline Alert'
+}
+
+export default _AlertInline
diff --git a/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.style.ts b/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.style.ts
new file mode 100644
index 000000000000..59b2314a7d93
--- /dev/null
+++ b/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.style.ts
@@ -0,0 +1,43 @@
+// Copyright (c) 2023 The Brave Authors. All rights reserved.
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import styled from 'styled-components'
+import { AlertType } from '../../../constants/types'
+
+import { LeoColors } from './leo-colors'
+
+export const InlineAlertContainer = styled.div<{
+ alertType: AlertType
+}>`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 16px;
+
+ margin-top: 16px;
+ margin-bottom: 16px;
+ padding: 16px;
+ width: 100%;
+ min-height: 56px;
+
+ border-radius: 8px;
+
+ color: ${LeoColors['light.text.primary']};
+ background-color: ${({ alertType }) =>
+ alertType === 'danger'
+ ? LeoColors['light.system.feedback.error.background']
+ : alertType === 'warning'
+ ? LeoColors['light.system.feedback.warning.background']
+ : 'unset'};
+ @media (prefers-color-scheme: dark) {
+ color: ${LeoColors['dark.text.primary']};
+ background-color: ${({ alertType }) =>
+ alertType === 'danger'
+ ? LeoColors['dark.system.feedback.error.background']
+ : alertType === 'warning'
+ ? LeoColors['dark.system.feedback.warning.background']
+ : 'unset'};
+ }
+`
diff --git a/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.tsx b/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.tsx
new file mode 100644
index 000000000000..3dedc4073da5
--- /dev/null
+++ b/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.tsx
@@ -0,0 +1,62 @@
+// Copyright (c) 2023 The Brave Authors. All rights reserved.
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import * as React from 'react'
+
+// types
+import { AlertType } from '../../../constants/types'
+
+// style
+import {
+ Column,
+ Text,
+ WarningCircleFilledIcon,
+ WarningTriangleFilledIcon
+} from '../../shared/style'
+import { InlineAlertContainer } from './alert-inline.style'
+
+interface Props {
+ alertType: AlertType
+ message: string
+ onDismiss?: () => void
+ onPrimaryClick?: () => void
+ onSecondaryClick?: () => void
+ primaryButtonText?: string
+ secondaryButtonText?: string
+ title?: string
+}
+
+const ICON_SIZE = { width: 16, height: 16 }
+
+export const AlertInline: React.FC = ({
+ alertType,
+ message,
+ onDismiss,
+ onPrimaryClick,
+ onSecondaryClick,
+ primaryButtonText,
+ secondaryButtonText,
+ title
+}) => {
+ return (
+
+
+ {alertType === 'danger' && (
+
+ )}
+ {alertType === 'warning' && (
+
+ )}
+
+
+
+ {message}
+
+
+
+ )
+}
+
+export default AlertInline
diff --git a/components/brave_wallet_ui/components/leo/alert-inline/leo-colors.ts b/components/brave_wallet_ui/components/leo/alert-inline/leo-colors.ts
new file mode 100644
index 000000000000..907c86c8ea6e
--- /dev/null
+++ b/components/brave_wallet_ui/components/leo/alert-inline/leo-colors.ts
@@ -0,0 +1,18 @@
+// Copyright (c) 2023 The Brave Authors. All rights reserved.
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+export const LeoColors = {
+ 'dark.system.feedback.error.background': '#410912',
+ 'dark.system.feedback.error.icon': '#EB637A',
+ 'dark.system.feedback.warning.background': '#281D00',
+ 'dark.system.feedback.warning.icon': '#BB8800',
+ 'dark.text.primary': '#ECEFF2',
+
+ 'light.system.feedback.error.background': '#FDF3F5',
+ 'light.system.feedback.error.icon': '#DC1D3C',
+ 'light.system.feedback.warning.background': '##FFF4D8',
+ 'light.system.feedback.warning.icon': '#E2A500',
+ 'light.text.primary': '#1D1F25'
+}
diff --git a/components/brave_wallet_ui/components/shared/style.tsx b/components/brave_wallet_ui/components/shared/style.tsx
index cf32249ec81c..cd2bb6e9f0c9 100644
--- a/components/brave_wallet_ui/components/shared/style.tsx
+++ b/components/brave_wallet_ui/components/shared/style.tsx
@@ -11,6 +11,9 @@ import { Link } from 'react-router-dom'
import { BraveWallet, StringWithAutocomplete } from '../../constants/types'
import IThemeProps from 'brave-ui/src/theme/theme-interface'
+// colors
+import { LeoColors } from '../leo/alert-inline/leo-colors'
+
// utils
import { stripERC20TokenImageURL } from '../../utils/string-utils'
@@ -27,6 +30,8 @@ import ClipboardSvg from '../../assets/svg-icons/copy-to-clipboard-icon.svg'
import DownloadSvg from '../../assets/svg-icons/download-icon.svg'
import CheckIconSvg from '../../assets/svg-icons/checkbox-check.svg'
import SwitchDown from '../../assets/svg-icons/switch-icon.svg'
+import WarningCircleFilled from '../../assets/svg-icons/warning-circle-icon.svg'
+import WarningTriangleFilled from '../../assets/svg-icons/warning-triangle-filled.svg'
export type ThemeColor = StringWithAutocomplete
@@ -296,6 +301,47 @@ export const GreenCheckmark = styled.div`
vertical-align: middle;
`
+export const WarningTriangleFilledIcon = styled.div<{
+ color?: keyof IThemeProps['color']
+}>`
+ mask-size: 100%;
+ background-color: ${(p) => p?.color
+ ? p.theme.color[p.color]
+ : LeoColors['light.system.feedback.warning.icon']
+ };
+ -webkit-mask-image: url(${WarningTriangleFilled});
+ mask-repeat: no-repeat;
+ mask-image: url(${WarningTriangleFilled});
+ @media (prefers-color-scheme: dark) {
+ color: ${(p) => p.theme.palette.blurple300};
+ background-color: ${(p) => p?.color
+ ? p.theme.color[p.color]
+ : LeoColors['dark.system.feedback.warning.icon']
+ };
+ }
+`
+
+export const WarningCircleFilledIcon = styled.div<{
+ color?: keyof IThemeProps['color']
+}>`
+ opacity: 50%;
+ mask-size: contain;
+ mask-position: center;
+ mask-repeat: no-repeat;
+ background-color: ${(p) => p?.color
+ ? p.theme.color[p.color]
+ : LeoColors['light.system.feedback.error.icon']
+ };
+ -webkit-mask-image: url(${WarningCircleFilled});
+ mask-image: url(${WarningCircleFilled});
+ @media (prefers-color-scheme: dark) {
+ background-color: ${(p) => p?.color
+ ? p.theme.color[p.color]
+ : LeoColors['dark.system.feedback.error.icon']
+ };
+ }
+`
+
export const CloseIcon = styled.div`
width: 20px;
height: 20px;
diff --git a/components/brave_wallet_ui/constants/types.ts b/components/brave_wallet_ui/constants/types.ts
index 2653c521b7f4..fd521e7011b3 100644
--- a/components/brave_wallet_ui/constants/types.ts
+++ b/components/brave_wallet_ui/constants/types.ts
@@ -995,3 +995,5 @@ export type AddressMessageInfo = {
description?: string
url?: string
}
+
+export type AlertType = 'danger' | 'warning' | 'info' | 'success'
diff --git a/components/brave_wallet_ui/stories/locale.ts b/components/brave_wallet_ui/stories/locale.ts
index df3be717df9c..63694283470d 100644
--- a/components/brave_wallet_ui/stories/locale.ts
+++ b/components/brave_wallet_ui/stories/locale.ts
@@ -594,6 +594,9 @@ provideStrings({
braveWalletEditGasSetSuggested: 'Set suggested',
braveWalletEditGasZeroGasPriceWarning: 'Transaction may not be propagated in the network.',
braveWalletEditGasLimitError: 'Gas limit must be an integer greater than 0',
+ braveWalletGasFeeLimitLowerThanBaseFeeWarning:
+ 'Fee limit is set lower than the base fee. ' +
+ 'Your transaction may take a long time or fail.',
// Advanced transaction settings
braveWalletAdvancedTransactionSettings: 'Advanced settings',
diff --git a/components/resources/wallet_strings.grdp b/components/resources/wallet_strings.grdp
index 48fcf418e59e..376330b05144 100644
--- a/components/resources/wallet_strings.grdp
+++ b/components/resources/wallet_strings.grdp
@@ -817,4 +817,5 @@
Token symbol is required
Token decimals of precision value is required
Mint address
+ Fee limit is set lower than the base fee. Your transaction may take a long time or fail.