Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(warning): Add generic gas fee warning component #6385

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions locales/base/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -2823,5 +2823,35 @@
"availableBalance": "Available: <0></0>",
"selectToken": "Select token",
"fiatPriceUnavailable": "Price unavailable"
},
"gasFeeWarning": {
"title": "You need more {{tokenSymbol}} for gas fees",
"descriptionMaxAmount": {
"sending": "Add {{tokenSymbol}} for gas fees or lower the amount you're sending",
"swapping": "Add {{tokenSymbol}} for gas fees or lower the amount you're swapping",
"depositing": "Add {{tokenSymbol}} for gas fees or lower the amount you're depositing",
"withdrawing": "Add {{tokenSymbol}} for gas fees or lower the amount you're withdrawing"
},
"descriptionNotEnoughGas": {
"sending": "Adjust the amount you're sending or add {{tokenSymbol}} to continue",
"swapping": "Adjust the amount you're swapping or add {{tokenSymbol}} to continue",
"depositing": "Adjust the amount you're depositing or add {{tokenSymbol}} to continue",
"withdrawing": "Adjust the amount you're withdrawing or add {{tokenSymbol}} to continue"
},
"titleDapp": "You have an insufficient gas token balance",
"descriptionDapp": "Add {{tokenSymbol}} to complete this transaction",
"cta": "Buy {{tokenSymbol}}",
"ctaGasToken": {
"send": "Send smaller amount",
"swap": "Swap smaller amount",
"deposit": "Deposit smaller amount",
"withdraw": "Withdraw smaller amount"
},
"verb": {
MuckT marked this conversation as resolved.
Show resolved Hide resolved
"send": "Send",
"swap": "Swap",
"deposit": "Deposit",
"withdraw": "Withdraw"
}
}
}
2 changes: 2 additions & 0 deletions src/analytics/Events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export enum AppEvents {
in_app_review_error = 'in_app_review_error',

handle_deeplink = 'handle_deeplink',

show_gas_fee_warning = 'show_gas_fee_warning',
}

export enum HomeEvents {
Expand Down
6 changes: 6 additions & 0 deletions src/analytics/Properties.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
} from 'src/analytics/types'
import { ErrorMessages } from 'src/app/ErrorMessages'
import { AddAssetsActionType } from 'src/components/AddAssetsBottomSheet'
import { GasFeeWarningFlow } from 'src/components/GasFeeWarning'
import { TokenPickerOrigin } from 'src/components/TokenBottomSheet'
import { DappSection } from 'src/dapps/types'
import { BeforeDepositActionName, EarnActiveMode, SerializableRewardsInfo } from 'src/earn/types'
Expand Down Expand Up @@ -152,6 +153,11 @@ interface AppEventsProperties {
fullPath: string | null
query: string | null
}
[AppEvents.show_gas_fee_warning]: {
flow: GasFeeWarningFlow
errorType: 'need-decrease-spend-amount-for-gas' | 'not-enough-balance-for-gas'
tokenId: string
}
}

interface HomeEventsProperties {
Expand Down
1 change: 1 addition & 0 deletions src/analytics/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export const eventDocs: Record<AnalyticsEventType, string> = {
[AppEvents.in_app_review_impression]: `User sees an in-app review request`,
[AppEvents.in_app_review_error]: `Error while attempting to display in-app review`,
[AppEvents.handle_deeplink]: `When a deeplink that leads into the app is detected and handled`,
[AppEvents.show_gas_fee_warning]: `When the gas fee warning is shown to the user`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[AppEvents.show_gas_fee_warning]: `When the gas fee warning is shown to the user`,
[AppEvents.gas_fee_warning_impression]: `When the gas fee warning is shown to the user`,

?

[HomeEvents.account_circle_tapped]: `When the account circle used in the tab navigation is tapped`,
[HomeEvents.profile_address_copy]: `When a user copies their wallet address from the profile screen`,
[HomeEvents.notification_scroll]: ``,
Expand Down
161 changes: 161 additions & 0 deletions src/components/GasFeeWarning.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { fireEvent, render } from '@testing-library/react-native'
import BigNumber from 'bignumber.js'
import React from 'react'
import { Provider } from 'react-redux'
import AppAnalytics from 'src/analytics/AppAnalytics'
import { AppEvents } from 'src/analytics/Events'
import GasFeeWarning, { GasFeeWarningFlow } from 'src/components/GasFeeWarning'
import {
PreparedTransactionsNeedDecreaseSpendAmountForGas,
PreparedTransactionsNotEnoughBalanceForGas,
PreparedTransactionsPossible,
} from 'src/viem/prepareTransactions'
import { createMockStore } from 'test/utils'
import { mockArbEthTokenId, mockCeloTokenId, mockTokenBalances } from 'test/values'

const mockPreparedTransactionPossible: PreparedTransactionsPossible = {
type: 'possible' as const,
transactions: [],
feeCurrency: {
...mockTokenBalances[mockArbEthTokenId],
isNative: true,
balance: new BigNumber(10),
priceUsd: new BigNumber(1),
lastKnownPriceUsd: new BigNumber(1),
},
}

const mockPreparedTransactionNotEnoughCelo: PreparedTransactionsNotEnoughBalanceForGas = {
type: 'not-enough-balance-for-gas' as const,
feeCurrencies: [
{
...mockTokenBalances[mockCeloTokenId],
isNative: true,
balance: new BigNumber(0),
priceUsd: new BigNumber(1500),
lastKnownPriceUsd: new BigNumber(1500),
},
],
}

const mockPreparedTransactionNeedDecreaseCelo: PreparedTransactionsNeedDecreaseSpendAmountForGas = {
type: 'need-decrease-spend-amount-for-gas' as const,
feeCurrency: {
...mockTokenBalances[mockCeloTokenId],
isNative: true,
balance: new BigNumber(0),
priceUsd: new BigNumber(1500),
lastKnownPriceUsd: new BigNumber(1500),
},
maxGasFeeInDecimal: new BigNumber(1),
estimatedGasFeeInDecimal: new BigNumber(1),
decreasedSpendAmount: new BigNumber(1),
}

const mockPreparedTransactionNotEnoughEth: PreparedTransactionsNotEnoughBalanceForGas = {
type: 'not-enough-balance-for-gas' as const,
feeCurrencies: [
{
...mockTokenBalances[mockArbEthTokenId],
isNative: true,
balance: new BigNumber(0),
priceUsd: new BigNumber(1500),
lastKnownPriceUsd: new BigNumber(1500),
},
],
}

const mockPreparedTransactionNeedDecreaseEth: PreparedTransactionsNeedDecreaseSpendAmountForGas = {
type: 'need-decrease-spend-amount-for-gas' as const,
feeCurrency: {
...mockTokenBalances[mockArbEthTokenId],
isNative: true,
balance: new BigNumber(0),
priceUsd: new BigNumber(1500),
lastKnownPriceUsd: new BigNumber(1500),
},
maxGasFeeInDecimal: new BigNumber(1),
estimatedGasFeeInDecimal: new BigNumber(1),
decreasedSpendAmount: new BigNumber(1),
}

describe('GasFeeWarning', () => {
beforeEach(() => {
jest.clearAllMocks()
})
it('should return null if prepareTransactionsResult is undefined', () => {
const store = createMockStore()
const { queryByTestId } = render(
<Provider store={store}>
<GasFeeWarning flow={GasFeeWarningFlow.Send} testIdPrefix={'test'} />
</Provider>
)
expect(queryByTestId('test/GasFeeWarning')).toBeFalsy()
})
it('should return null if prepareTransactionsResult.type is possible', () => {
const store = createMockStore()
const { queryByTestId } = render(
<Provider store={store}>
<GasFeeWarning
flow={GasFeeWarningFlow.Send}
testIdPrefix={'test'}
prepareTransactionsResult={mockPreparedTransactionPossible}
/>
</Provider>
)
expect(queryByTestId('test/GasFeeWarning')).toBeFalsy()
})
it.each`
scenario | flow | prepareTransactionsResult | feeCurrencyTokenId | title | description | ctaLabel
Copy link
Contributor

@satish-ravi satish-ravi Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it doesn't hurt but whats the value of testing all the different variants with 2 different symbols? We don't seem to be doing anything custom depending on symbols

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to have test coverage for all the cases outlined by product in the figma doc, and those cases include Celo and non-Celo chains so I had one of each

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I guess figma had those differences because celo is the only one with multiple gas tokens, we don't really handle that in this component, so it seems superfluous to test the variations.

${'sending max amount of CELO'} | ${GasFeeWarningFlow.Send} | ${mockPreparedTransactionNeedDecreaseCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.descriptionMaxAmount.sending, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.ctaGasToken.send'}
${'sending max amount of ETH'} | ${GasFeeWarningFlow.Send} | ${mockPreparedTransactionNeedDecreaseEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.descriptionMaxAmount.sending, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.ctaGasToken.send'}
${'sending with insufficient CELO'} | ${GasFeeWarningFlow.Send} | ${mockPreparedTransactionNotEnoughCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.descriptionNotEnoughGas.sending, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.cta, {"tokenSymbol":"CELO"}'}
${'sending with insufficient ETH'} | ${GasFeeWarningFlow.Send} | ${mockPreparedTransactionNotEnoughEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.descriptionNotEnoughGas.sending, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.cta, {"tokenSymbol":"ETH"}'}
${'swapping max amount of CELO'} | ${GasFeeWarningFlow.Swap} | ${mockPreparedTransactionNeedDecreaseCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.descriptionMaxAmount.swapping, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.ctaGasToken.swap'}
${'swapping max amount of ETH'} | ${GasFeeWarningFlow.Swap} | ${mockPreparedTransactionNeedDecreaseEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.descriptionMaxAmount.swapping, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.ctaGasToken.swap'}
${'swapping with insufficient CELO'} | ${GasFeeWarningFlow.Swap} | ${mockPreparedTransactionNotEnoughCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.descriptionNotEnoughGas.swapping, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.cta, {"tokenSymbol":"CELO"}'}
${'swapping with insufficient ETH'} | ${GasFeeWarningFlow.Swap} | ${mockPreparedTransactionNotEnoughEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.descriptionNotEnoughGas.swapping, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.cta, {"tokenSymbol":"ETH"}'}
${'withdrawing max amount of CELO'} | ${GasFeeWarningFlow.Withdraw} | ${mockPreparedTransactionNeedDecreaseCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.descriptionMaxAmount.withdrawing, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.ctaGasToken.withdraw'}
${'withdrawing max amount of ETH'} | ${GasFeeWarningFlow.Withdraw} | ${mockPreparedTransactionNeedDecreaseEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.descriptionMaxAmount.withdrawing, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.ctaGasToken.withdraw'}
${'withdrawing with insufficient CELO'} | ${GasFeeWarningFlow.Withdraw} | ${mockPreparedTransactionNotEnoughCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.descriptionNotEnoughGas.withdrawing, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.cta, {"tokenSymbol":"CELO"}'}
${'withdrawing with insufficient ETH'} | ${GasFeeWarningFlow.Withdraw} | ${mockPreparedTransactionNotEnoughEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.descriptionNotEnoughGas.withdrawing, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.cta, {"tokenSymbol":"ETH"}'}
${'depositing max amount of CELO'} | ${GasFeeWarningFlow.Deposit} | ${mockPreparedTransactionNeedDecreaseCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.descriptionMaxAmount.depositing, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.ctaGasToken.deposit'}
${'depositing max amount of ETH'} | ${GasFeeWarningFlow.Deposit} | ${mockPreparedTransactionNeedDecreaseEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.descriptionMaxAmount.depositing, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.ctaGasToken.deposit'}
${'depositing with insufficient CELO'} | ${GasFeeWarningFlow.Deposit} | ${mockPreparedTransactionNotEnoughCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.descriptionNotEnoughGas.depositing, {"tokenSymbol":"CELO"}'} | ${'gasFeeWarning.cta, {"tokenSymbol":"CELO"}'}
${'depositing with insufficient ETH'} | ${GasFeeWarningFlow.Deposit} | ${mockPreparedTransactionNotEnoughEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.title, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.descriptionNotEnoughGas.depositing, {"tokenSymbol":"ETH"}'} | ${'gasFeeWarning.cta, {"tokenSymbol":"ETH"}'}
${'dapp transaction with max amount of CELO'} | ${GasFeeWarningFlow.Dapp} | ${mockPreparedTransactionNeedDecreaseCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.titleDapp'} | ${'gasFeeWarning.descriptionDapp, {"tokenSymbol":"CELO"}'} | ${undefined}
${'dapp transaction with max amount of ETH'} | ${GasFeeWarningFlow.Dapp} | ${mockPreparedTransactionNeedDecreaseEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.titleDapp'} | ${'gasFeeWarning.descriptionDapp, {"tokenSymbol":"ETH"}'} | ${undefined}
${'dapp transaction with insufficient CELO'} | ${GasFeeWarningFlow.Dapp} | ${mockPreparedTransactionNotEnoughCelo} | ${mockCeloTokenId} | ${'gasFeeWarning.titleDapp'} | ${'gasFeeWarning.descriptionDapp, {"tokenSymbol":"CELO"}'} | ${undefined}
${'dapp transaction with insufficient ETH'} | ${GasFeeWarningFlow.Dapp} | ${mockPreparedTransactionNotEnoughEth} | ${mockArbEthTokenId} | ${'gasFeeWarning.titleDapp'} | ${'gasFeeWarning.descriptionDapp, {"tokenSymbol":"ETH"}'} | ${undefined}
`(
'renders error correctly when $scenario',
({ flow, prepareTransactionsResult, feeCurrencyTokenId, title, description, ctaLabel }) => {
const store = createMockStore()
const onPressCta = jest.fn()
const { getByTestId, getByText } = render(
<Provider store={store}>
<GasFeeWarning
flow={flow}
testIdPrefix={'test'}
prepareTransactionsResult={prepareTransactionsResult}
onPressCta={ctaLabel ? onPressCta : undefined}
/>
</Provider>
)
expect(getByTestId('test/GasFeeWarning')).toBeTruthy()
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(AppEvents.show_gas_fee_warning, {
flow,
errorType: prepareTransactionsResult.type,
tokenId: feeCurrencyTokenId,
})
expect(getByText(title)).toBeTruthy()
expect(getByText(description)).toBeTruthy()
if (ctaLabel) {
fireEvent.press(getByText(ctaLabel))
}
expect(ctaLabel ? getByText(ctaLabel) : true).toBeTruthy()
expect(onPressCta).toHaveBeenCalledTimes(ctaLabel ? 1 : 0)
}
)
})
124 changes: 124 additions & 0 deletions src/components/GasFeeWarning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { StyleSheet } from 'react-native'
import AppAnalytics from 'src/analytics/AppAnalytics'
import { AppEvents } from 'src/analytics/Events'
import InLineNotification, { NotificationVariant } from 'src/components/InLineNotification'
import { Spacing } from 'src/styles/styles'
import { PreparedTransactionsResult } from 'src/viem/prepareTransactions'

export enum GasFeeWarningFlow {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you consider string literals over enum for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no but I can change it to that, in Valora should we prefer string literals over enums? Or what is the convention?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think we have a defined convention, but we did talk about this in an eng sync and I think we've been favoring literals over enums recently

Send = 'Send',
Swap = 'Swap',
Deposit = 'Deposit',
Withdraw = 'Withdraw',
Dapp = 'Dapp',
}

function GasFeeWarning({
prepareTransactionsResult,
flow,
onPressCta,
testIdPrefix,
}: {
prepareTransactionsResult?: PreparedTransactionsResult
flow: GasFeeWarningFlow
onPressCta?: () => void
testIdPrefix?: string
}) {
const { t } = useTranslation()

useEffect(() => {
if (prepareTransactionsResult && prepareTransactionsResult.type !== 'possible') {
AppAnalytics.track(AppEvents.show_gas_fee_warning, {
flow,
errorType: prepareTransactionsResult.type,
tokenId: feeCurrency.tokenId,
})
}
}, [prepareTransactionsResult])

if (!prepareTransactionsResult || prepareTransactionsResult.type === 'possible') {
return false
}

const feeCurrency =
prepareTransactionsResult.type === 'not-enough-balance-for-gas'
? prepareTransactionsResult.feeCurrencies[0]
: prepareTransactionsResult.feeCurrency

const flowToNotEnoughGasDescriptionString = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can consider using context instead of doing this mapping yourself. E.g., the translation strings could be made something like gasFeeWarning.description.notEnoughGas_<GasFeeWarningFlow>, and then you can just do t('gasFeeWarning.description.notEnoughGas', { context: <GasFeeWarningFlow>, tokenSymbol })
There are other places in the app where we do this if you want a complete example

[GasFeeWarningFlow.Send]: t('gasFeeWarning.descriptionNotEnoughGas.sending', {
tokenSymbol: feeCurrency.symbol,
}),
[GasFeeWarningFlow.Swap]: t('gasFeeWarning.descriptionNotEnoughGas.swapping', {
tokenSymbol: feeCurrency.symbol,
}),
[GasFeeWarningFlow.Deposit]: t('gasFeeWarning.descriptionNotEnoughGas.depositing', {
tokenSymbol: feeCurrency.symbol,
}),
[GasFeeWarningFlow.Withdraw]: t('gasFeeWarning.descriptionNotEnoughGas.withdrawing', {
tokenSymbol: feeCurrency.symbol,
}),
}

const flowToDescreasSpendDescriptionString = {
[GasFeeWarningFlow.Send]: t('gasFeeWarning.descriptionMaxAmount.sending', {
tokenSymbol: feeCurrency.symbol,
}),
[GasFeeWarningFlow.Swap]: t('gasFeeWarning.descriptionMaxAmount.swapping', {
tokenSymbol: feeCurrency.symbol,
}),
[GasFeeWarningFlow.Deposit]: t('gasFeeWarning.descriptionMaxAmount.depositing', {
tokenSymbol: feeCurrency.symbol,
}),
[GasFeeWarningFlow.Withdraw]: t('gasFeeWarning.descriptionMaxAmount.withdrawing', {
tokenSymbol: feeCurrency.symbol,
}),
}

const flowToCtaString = {
[GasFeeWarningFlow.Send]: t('gasFeeWarning.ctaGasToken.send'),
[GasFeeWarningFlow.Swap]: t('gasFeeWarning.ctaGasToken.swap'),
[GasFeeWarningFlow.Deposit]: t('gasFeeWarning.ctaGasToken.deposit'),
[GasFeeWarningFlow.Withdraw]: t('gasFeeWarning.ctaGasToken.withdraw'),
}

const title =
flow === GasFeeWarningFlow.Dapp
? t('gasFeeWarning.titleDapp')
: t('gasFeeWarning.title', { tokenSymbol: feeCurrency.symbol })
const description =
flow === GasFeeWarningFlow.Dapp
? t('gasFeeWarning.descriptionDapp', { tokenSymbol: feeCurrency.symbol })
: prepareTransactionsResult.type === 'not-enough-balance-for-gas'
? flowToNotEnoughGasDescriptionString[flow]
: flowToDescreasSpendDescriptionString[flow]
const ctaLabel =
flow === GasFeeWarningFlow.Dapp
? undefined
: prepareTransactionsResult.type === 'not-enough-balance-for-gas'
? t('gasFeeWarning.cta', { tokenSymbol: feeCurrency.symbol })
: flowToCtaString[flow]
return (
<InLineNotification
variant={NotificationVariant.Warning}
title={title}
description={description}
ctaLabel={ctaLabel}
onPressCta={onPressCta}
style={styles.warning}
testID={`${testIdPrefix}/GasFeeWarning`}
/>
)
}

const styles = StyleSheet.create({
warning: {
marginTop: Spacing.Regular16,
paddingHorizontal: Spacing.Regular16,
borderRadius: 16,
},
})

export default GasFeeWarning
10 changes: 3 additions & 7 deletions src/earn/EarnEnterAmount.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ describe('EarnEnterAmount', () => {
})
})

it('should track analytics and navigate correctly when tapping cta to add gas', async () => {
it('should show gas warning error when prepareTransactionsResult is type not-enough-balance-for-gas, and tapping cta behaves as expected', async () => {
jest.mocked(usePrepareEnterAmountTransactionsCallback).mockReturnValue({
prepareTransactionsResult: {
prepareTransactionsResult: mockPreparedTransactionNotEnough,
Expand All @@ -934,12 +934,8 @@ describe('EarnEnterAmount', () => {
</Provider>
)

await waitFor(() => expect(getByTestId('EarnEnterAmount/NotEnoughForGasWarning')).toBeTruthy())
fireEvent.press(
getByText(
'earnFlow.enterAmount.notEnoughBalanceForGasWarning.noGasCta, {"feeTokenSymbol":"ETH","network":"Arbitrum Sepolia"}'
)
)
await waitFor(() => expect(getByTestId('EarnEnterAmount/GasFeeWarning')).toBeTruthy())
fireEvent.press(getByText('gasFeeWarning.cta, {"tokenSymbol":"ETH"}'))
expect(AppAnalytics.track).toHaveBeenCalledWith(EarnEvents.earn_deposit_add_gas_press, {
gasTokenId: mockArbEthTokenId,
networkId: NetworkId['arbitrum-sepolia'],
Expand Down
Loading
Loading