diff --git a/android/app/src/main/res/drawable-hdpi/networks.png b/android/app/src/main/res/drawable-hdpi/networks.png new file mode 100644 index 000000000..4d3695740 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/networks.png differ diff --git a/android/app/src/main/res/drawable-mdpi/networks.png b/android/app/src/main/res/drawable-mdpi/networks.png new file mode 100644 index 000000000..92d56f598 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/networks.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/networks.png b/android/app/src/main/res/drawable-xhdpi/networks.png new file mode 100644 index 000000000..3a025a0c1 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/networks.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/networks.png b/android/app/src/main/res/drawable-xxhdpi/networks.png new file mode 100644 index 000000000..9c59992ed Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/networks.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/networks.png b/android/app/src/main/res/drawable-xxxhdpi/networks.png new file mode 100644 index 000000000..1e9ee03b8 Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/networks.png differ diff --git a/index.js b/index.js index 375cd54b3..0d4f54f5c 100644 --- a/index.js +++ b/index.js @@ -22,6 +22,7 @@ import {name as appName} from './app.json'; import {App} from './src/app'; import './src/event-actions'; import {Jailbreak} from './src/jailbreak'; +import {Provider} from '@app/models/provider'; if (!global.BigInt) { const BigInt = require('big-integer'); @@ -100,8 +101,8 @@ JsonRpcProvider.prototype.send = async function (method, params) { const eventParams = { type: 'EVM', - network: app.provider.name, - chainId: `${app.provider.ethChainId}`, + network: Provider.selectedProvider.name, + chainId: `${Provider.selectedProvider.ethChainId}`, address: parsedAddressFrom, }; diff --git a/ios/haqq/Images.xcassets/networks.imageset/Contents.json b/ios/haqq/Images.xcassets/networks.imageset/Contents.json new file mode 100644 index 000000000..9f0cb4d8e --- /dev/null +++ b/ios/haqq/Images.xcassets/networks.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images": [ + { + "filename": "networks.svg", + "idiom": "universal" + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/ios/haqq/Images.xcassets/networks.imageset/networks.svg b/ios/haqq/Images.xcassets/networks.imageset/networks.svg new file mode 100644 index 000000000..7c9ba6b06 --- /dev/null +++ b/ios/haqq/Images.xcassets/networks.imageset/networks.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/package.json b/package.json index 44d6375f9..cf08ca03f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "haqq", - "version": "1.9.1", + "version": "1.9.2", "private": true, "scripts": { "android": "react-native run-android", diff --git a/src/app.tsx b/src/app.tsx index 876fa28c7..58494991b 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -125,7 +125,7 @@ export const App = () => { sleep(150) .then(async () => await app.awaitForInitialization()) .then(() => SplashScreen.hide()) - .then(() => awaitForEventDone(Events.onAppInitialized)) + .then(async () => await awaitForEventDone(Events.onAppInitialized)) .then(async () => await Language.init()) .then(async () => { await Stories.fetch(true); diff --git a/src/components/account-detail.tsx b/src/components/account-detail.tsx index 67de5d7f2..9a89f050c 100644 --- a/src/components/account-detail.tsx +++ b/src/components/account-detail.tsx @@ -21,9 +21,9 @@ import { InfoBlock, Text, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Wallet} from '@app/models/wallet'; import {sendNotification} from '@app/services'; import {GRADIENT_END, GRADIENT_START} from '@app/variables/common'; @@ -76,7 +76,7 @@ export const AccountDetail = observer( title={I18N.evmTitle} component={null} /> - {app.provider.config.isBech32Enabled && ( + {Provider.selectedProvider.config.isBech32Enabled && ( } /> diff --git a/src/components/animated-balance.tsx b/src/components/animated-balance.tsx index 0372637c8..b8776ffbd 100644 --- a/src/components/animated-balance.tsx +++ b/src/components/animated-balance.tsx @@ -5,8 +5,8 @@ import Timer from 'react-timer-mixin'; import {Color, getColor} from '@app/colors'; import {Text, TextVariant} from '@app/components/ui'; -import {app} from '@app/contexts'; import {cleanNumber, createTheme} from '@app/helpers'; +import {Provider} from '@app/models/provider'; type Props = { value: number; @@ -85,7 +85,7 @@ export class AnimateNumber extends Component { color={Color.textBase3} numberOfLines={1} style={styles.currencySuffixText}> - {` ${app.provider.denom}`} + {` ${Provider.selectedProvider.denom}`} ); diff --git a/src/components/home-earn.tsx b/src/components/home-earn.tsx index be733cdde..8203fa8b6 100644 --- a/src/components/home-earn.tsx +++ b/src/components/home-earn.tsx @@ -5,10 +5,10 @@ import {RefreshControl, ScrollView, TouchableOpacity, View} from 'react-native'; import {RiveRef} from 'rive-react-native'; import {Color} from '@app/colors'; -import {app} from '@app/contexts'; import {cleanNumber, createTheme} from '@app/helpers'; import {useThemeSelector} from '@app/hooks'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Raffle} from '@app/types'; import {SHADOW_L} from '@app/variables/shadows'; @@ -114,7 +114,7 @@ export const HomeEarn = observer( variant={TextVariant.t14} color={Color.textBase2} i18n={I18N.earnStakingDescription} - i18params={{symbol: app.provider.denom}} + i18params={{symbol: Provider.selectedProvider.denom}} /> @@ -129,7 +129,7 @@ export const HomeEarn = observer( - {`${formattedRewardAmount} ${app.provider.denom}`} + {`${formattedRewardAmount} ${Provider.selectedProvider.denom}`} {showStakingGetRewardsButtons && ( diff --git a/src/components/home-staking/staking-active.tsx b/src/components/home-staking/staking-active.tsx index 6a3bc2c7d..725c8355f 100644 --- a/src/components/home-staking/staking-active.tsx +++ b/src/components/home-staking/staking-active.tsx @@ -20,10 +20,10 @@ import { TextPosition, TextVariant, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {useTheme} from '@app/hooks'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Balance} from '@app/services/balance'; import {AppTheme} from '@app/types'; import {IS_IOS} from '@app/variables/common'; @@ -106,7 +106,7 @@ export const StakingActive = observer( position={TextPosition.center} color={Color.textBase2} i18n={I18N.homeStakingEmpty} - i18params={{symbol: app.provider.denom}} + i18params={{symbol: Provider.selectedProvider.denom}} /> { position={TextPosition.center} color={Color.textBase2} i18n={I18N.homeStakingEmpty} - i18params={{symbol: app.provider.denom}} + i18params={{symbol: Provider.selectedProvider.denom}} /> diff --git a/src/components/json-rpc-sign/json-rpc-common-transaction.tsx b/src/components/json-rpc-sign/json-rpc-common-transaction.tsx index 758cf7d5e..517623612 100644 --- a/src/components/json-rpc-sign/json-rpc-common-transaction.tsx +++ b/src/components/json-rpc-sign/json-rpc-common-transaction.tsx @@ -20,7 +20,7 @@ import {shortAddress} from '@app/helpers/short-address'; import {I18N} from '@app/i18n'; import {Contracts} from '@app/models/contracts'; import {Fee} from '@app/models/fee'; -import {Provider} from '@app/models/provider'; +import {ProviderModel} from '@app/models/provider'; import {Token} from '@app/models/tokens'; import {Balance} from '@app/services/balance'; import {JsonRpcMetadata, JsonRpcTransactionRequest} from '@app/types'; @@ -34,7 +34,7 @@ export interface JsonRpcCommonTransactionProps { showSignContratAttention: boolean; functionName?: string; isContract: boolean; - provider: Provider | undefined; + provider: ProviderModel | undefined; isFeeLoading: boolean; fee: Fee | null | undefined; tx: Partial | undefined; diff --git a/src/components/json-rpc-sign/json-rpc-swap-transaction.tsx b/src/components/json-rpc-sign/json-rpc-swap-transaction.tsx index f9f433a5f..25e5d3da4 100644 --- a/src/components/json-rpc-sign/json-rpc-swap-transaction.tsx +++ b/src/components/json-rpc-sign/json-rpc-swap-transaction.tsx @@ -29,7 +29,7 @@ import {I18N} from '@app/i18n'; import {Contracts} from '@app/models/contracts'; import {Currencies} from '@app/models/currencies'; import {Fee} from '@app/models/fee'; -import {Provider} from '@app/models/provider'; +import {ProviderModel} from '@app/models/provider'; import {Token} from '@app/models/tokens'; import {Wallet} from '@app/models/wallet'; import {Balance} from '@app/services/balance'; @@ -50,7 +50,7 @@ import { export interface JsonRpcSwapTransactionProps { metadata: JsonRpcMetadata; - provider: Provider | undefined; + provider: ProviderModel | undefined; isFeeLoading: boolean; functionName: string; fee: Fee | null | undefined; diff --git a/src/components/json-rpc-sign/json-rpc-transaction-info.tsx b/src/components/json-rpc-sign/json-rpc-transaction-info.tsx index 1f63295e1..779dfe944 100644 --- a/src/components/json-rpc-sign/json-rpc-transaction-info.tsx +++ b/src/components/json-rpc-sign/json-rpc-transaction-info.tsx @@ -1,6 +1,7 @@ import React, {useCallback, useMemo, useState} from 'react'; -import {app} from '@app/contexts'; +import {observer} from 'mobx-react'; + import {awaitForFee} from '@app/helpers/await-for-fee'; import {useTypedNavigation} from '@app/hooks'; import {useEffectAsync} from '@app/hooks/use-effect-async'; @@ -38,164 +39,168 @@ interface JsonRpcTransactionInfoProps { setFeeLoading: React.Dispatch>; } -export const JsonRpcTransactionInfo = ({ - request, - metadata, - verifyAddressResponse, - chainId, - hideContractAttention, - fee, - setFee, - isFeeLoading, - setFeeLoading, -}: JsonRpcTransactionInfoProps) => { - const navigation = useTypedNavigation(); - - const [isSwapRenderError, setIsSwapRenderError] = useState(false); - - const tx = useMemo( - () => getTransactionFromJsonRpcRequest(request), - [request], - ); - - const provider = useMemo(() => { - return Provider.getByEthChainId( - tx?.chainId ?? chainId ?? app.provider.ethChainId, +export const JsonRpcTransactionInfo = observer( + ({ + request, + metadata, + verifyAddressResponse, + chainId, + hideContractAttention, + fee, + setFee, + isFeeLoading, + setFeeLoading, + }: JsonRpcTransactionInfoProps) => { + const navigation = useTypedNavigation(); + + const [isSwapRenderError, setIsSwapRenderError] = useState(false); + + const tx = useMemo( + () => getTransactionFromJsonRpcRequest(request), + [request], + ); + + const provider = useMemo(() => { + return Provider.getByEthChainId( + tx?.chainId ?? chainId ?? Provider.selectedProvider.ethChainId, + ); + }, [chainId, tx]); + + const isContract = useMemo( + () => + verifyAddressResponse?.address_type === AddressType.contract || + isContractTransaction(tx), + [tx, verifyAddressResponse], + ); + + const isInWhiteList = useMemo( + () => !!verifyAddressResponse?.is_in_white_list, + [verifyAddressResponse], + ); + + const showSignContratAttention = + !hideContractAttention && isContract && !isInWhiteList; + + const txParsedData = useMemo(() => parseTxDataFromHexInput(tx?.data), [tx]); + + const functionName = useMemo(() => { + if (txParsedData) { + return txParsedData.name; + } + return ''; + }, [txParsedData]); + + const isSwapTx = useMemo( + () => ['exactInput', 'deposit', 'withdraw'].includes(functionName), + [functionName], ); - }, [chainId, tx]); - - const isContract = useMemo( - () => - verifyAddressResponse?.address_type === AddressType.contract || - isContractTransaction(tx), - [tx, verifyAddressResponse], - ); - - const isInWhiteList = useMemo( - () => !!verifyAddressResponse?.is_in_white_list, - [verifyAddressResponse], - ); - - const showSignContratAttention = - !hideContractAttention && isContract && !isInWhiteList; - - const txParsedData = useMemo(() => parseTxDataFromHexInput(tx?.data), [tx]); - - const functionName = useMemo(() => { - if (txParsedData) { - return txParsedData.name; - } - return ''; - }, [txParsedData]); - - const isSwapTx = useMemo( - () => ['exactInput', 'deposit', 'withdraw'].includes(functionName), - [functionName], - ); - - const calculateFee = useCallback(async () => { - if (!tx) { - return Balance.Empty; - } - - try { - const data = await EthNetwork.estimate( - { + + const calculateFee = useCallback(async () => { + if (!tx) { + return Balance.Empty; + } + + try { + const data = await EthNetwork.estimate( + { + from: tx.from!, + to: tx.to!, + value: new Balance( + tx.value || Balance.Empty, + provider?.decimals, + provider?.denom, + ), + data: tx.data, + }, + EstimationVariant.average, + provider, + ); + setFee(new Fee(data)); + return data.expectedFee; + } catch { + return Balance.Empty; + } + }, [tx, provider]); + + const onFeePress = useCallback(async () => { + if (!tx) { + return; + } + + if (fee) { + const result = await awaitForFee({ + fee, from: tx.from!, to: tx.to!, value: new Balance( - tx.value || Balance.Empty, + tx.value! || Balance.Empty, provider?.decimals, provider?.denom, ), data: tx.data, - }, - EstimationVariant.average, - provider, - ); - setFee(new Fee(data)); - return data.expectedFee; - } catch { - return Balance.Empty; - } - }, [tx, provider]); - - const onFeePress = useCallback(async () => { - if (!tx) { - return; - } - - if (fee) { - const result = await awaitForFee({ - fee, - from: tx.from!, - to: tx.to!, - value: new Balance( - tx.value! || Balance.Empty, - provider?.decimals, - provider?.denom, - ), - data: tx.data, - chainId: provider?.ethChainId ? String(provider.ethChainId) : undefined, - }); - setFee(result); - } - }, [navigation, tx, fee, provider]); - - const onSwapRenderError = useCallback(() => { - setIsSwapRenderError(true); - }, []); - - useEffectAsync(async () => { - if (!fee?.calculatedFees) { - try { - if (tx) { - setFeeLoading(true); - await calculateFee(); - } - } catch (err) { - Logger.captureException(err, 'JsonRpcTransactionInfo:calculateFee', { - params: tx, - chainId, + chainId: provider?.ethChainId + ? String(provider.ethChainId) + : undefined, }); - } finally { + setFee(result); + } + }, [navigation, tx, fee, provider]); + + const onSwapRenderError = useCallback(() => { + setIsSwapRenderError(true); + }, []); + + useEffectAsync(async () => { + if (!fee?.calculatedFees) { + try { + if (tx) { + setFeeLoading(true); + await calculateFee(); + } + } catch (err) { + Logger.captureException(err, 'JsonRpcTransactionInfo:calculateFee', { + params: tx, + chainId, + }); + } finally { + setFeeLoading(false); + } + } else { setFeeLoading(false); } - } else { - setFeeLoading(false); - } - }, [chainId]); - - return ( - - {!isSwapRenderError && isSwapTx && isContract && ( - + {!isSwapRenderError && isSwapTx && isContract && ( + + )} + + - )} - - - - ); -}; + + ); + }, +); diff --git a/src/components/locked-tokens.tsx b/src/components/locked-tokens.tsx index 46ef3875a..a885cbb89 100644 --- a/src/components/locked-tokens.tsx +++ b/src/components/locked-tokens.tsx @@ -4,10 +4,10 @@ import {observer} from 'mobx-react'; import {View} from 'react-native'; import {Color} from '@app/colors'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {useIsBalancesFirstSync} from '@app/hooks/use-is-balances-sync'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {BalanceData} from '@app/types'; import { @@ -34,8 +34,8 @@ export const LockedTokens = observer( const {isBalanceLoadingError, isBalancesFirstSync} = useIsBalancesFirstSync(); const defaultTotalValueISLM = useMemo( - () => `0 ${app.provider.denom}`, - [app.provider.denom], + () => `0 ${Provider.selectedProvider.denom}`, + [Provider.selectedProvider.denom], ); const defaultTotalValueUSD = useMemo(() => '$0', []); diff --git a/src/components/modals/details-qr.tsx b/src/components/modals/details-qr.tsx index 732a6a66b..e52cb4108 100644 --- a/src/components/modals/details-qr.tsx +++ b/src/components/modals/details-qr.tsx @@ -17,9 +17,9 @@ import { InfoBlock, Text, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Wallet} from '@app/models/wallet'; import {sendNotification} from '@app/services'; import {ModalType, Modals} from '@app/types'; @@ -52,8 +52,8 @@ export const DetailsQrModal = observer( style={page.info} i18n={I18N.modalDetailsQRWarning} i18params={{ - assetName: app.provider.denom, - networkName: app.provider.name, + assetName: Provider.selectedProvider.denom, + networkName: Provider.selectedProvider.name, }} icon={} /> diff --git a/src/components/modals/providers-bottom-sheet.tsx b/src/components/modals/providers-bottom-sheet.tsx index bd4608a48..c1124cb86 100644 --- a/src/components/modals/providers-bottom-sheet.tsx +++ b/src/components/modals/providers-bottom-sheet.tsx @@ -9,8 +9,10 @@ import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {useCalculatedDimensionsValue} from '@app/hooks/use-calculated-dimensions-value'; import {I18N} from '@app/i18n'; +import {ALL_NETWORKS_ID} from '@app/models/provider'; import {ModalType, Modals} from '@app/types'; +import {SettingsProvidersAllNetworksRow} from '../settings/settings-providers/settings-providers-all-networks-row'; import {SettingsProvidersRow} from '../settings/settings-providers/settings-providers-row'; export function ProvidersBottomSheet({ @@ -87,17 +89,30 @@ export function ProvidersBottomSheet({ leading={ } + style={styles.searchField} /> item.id} - renderItem={({item}) => ( - - )} + renderItem={({item}) => { + if (item.id === ALL_NETWORKS_ID) { + return ( + + ); + } + + return ( + + ); + }} /> @@ -108,4 +123,5 @@ const styles = createTheme({ container: { height: '50%', }, + searchField: {marginBottom: 16}, }); diff --git a/src/components/proposal-deposit-finish/proposal-deposit-finish.tsx b/src/components/proposal-deposit-finish/proposal-deposit-finish.tsx index 4f2eaf552..f47a18b9d 100644 --- a/src/components/proposal-deposit-finish/proposal-deposit-finish.tsx +++ b/src/components/proposal-deposit-finish/proposal-deposit-finish.tsx @@ -19,10 +19,10 @@ import { TextVariant, } from '@app/components/ui'; import {NetworkFee} from '@app/components/ui/network-fee'; -import {app} from '@app/contexts'; import {createTheme, openURL} from '@app/helpers'; import {cleanNumber} from '@app/helpers/clean-number'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Balance} from '@app/services/balance'; export type ProposalDepositFinishProps = { @@ -65,7 +65,7 @@ export const ProposalDepositFinish = observer( variant={TextVariant.t3} position={TextPosition.center} style={styles.sum}> - {`${cleanNumber(amount)} ${app.provider.denom}`} + {`${cleanNumber(amount)} ${Provider.selectedProvider.denom}`} { const transactionFee = useMemo(() => { - const maximumFee = fee.compare(FEE_AMOUNT, 'gt') ? fee : FEE_AMOUNT; + const maximumFee = fee.compare(new Balance(FEE_AMOUNT), 'gt') + ? fee + : new Balance(FEE_AMOUNT); return new Balance(maximumFee); }, [fee]); const amounts = useSumAmount( diff --git a/src/components/proposal-deposit-preview/proposal-deposit-preview.tsx b/src/components/proposal-deposit-preview/proposal-deposit-preview.tsx index da527fd72..1d627f0eb 100644 --- a/src/components/proposal-deposit-preview/proposal-deposit-preview.tsx +++ b/src/components/proposal-deposit-preview/proposal-deposit-preview.tsx @@ -15,10 +15,10 @@ import { TextPosition, TextVariant, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {cleanNumber} from '@app/helpers/clean-number'; import {I18N, getText} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Balance} from '@app/services/balance'; export type ProposalDepositPreviewProps = { @@ -56,7 +56,7 @@ export const ProposalDepositPreview = observer( variant={TextVariant.t3} position={TextPosition.center} style={styles.sum}> - {`${cleanNumber(amount)} ${app.provider.denom}`} + {`${cleanNumber(amount)} ${Provider.selectedProvider.denom}`} diff --git a/src/components/raffle-details.tsx b/src/components/raffle-details.tsx index 90c2efc37..a49ff6ccd 100644 --- a/src/components/raffle-details.tsx +++ b/src/components/raffle-details.tsx @@ -4,10 +4,10 @@ import {observer} from 'mobx-react'; import {Image, View} from 'react-native'; import {Color} from '@app/colors'; -import {app} from '@app/contexts'; import {cleanNumber, createTheme} from '@app/helpers'; import {useTimer} from '@app/hooks/use-timer'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Raffle, TimerUpdateInterval} from '@app/types'; import {WEI} from '@app/variables/common'; @@ -96,7 +96,7 @@ export const RaffleDetails = observer( source={require('@assets/images/islm_icon.png')} /> - {`${formattedBudget} ${app.provider.denom}`} + {`${formattedBudget} ${Provider.selectedProvider.denom}`} @@ -145,7 +145,7 @@ export const RaffleDetails = observer( i18params={{ islm: cleanNumber(prevIslmCount), tickets: `${prevTicketsCount} `, - symbol: app.provider.denom, + symbol: Provider.selectedProvider.denom, }} /> diff --git a/src/components/raffle-reward.tsx b/src/components/raffle-reward.tsx index 6e3801bf4..017ce6510 100644 --- a/src/components/raffle-reward.tsx +++ b/src/components/raffle-reward.tsx @@ -4,10 +4,10 @@ import {observer} from 'mobx-react'; import {Image, SafeAreaView, StyleSheet, View} from 'react-native'; import {Color} from '@app/colors'; -import {app} from '@app/contexts'; import {cleanNumber} from '@app/helpers'; import {useThemeSelector} from '@app/hooks'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Raffle} from '@app/types'; import {WEI} from '@app/variables/common'; @@ -79,7 +79,7 @@ export const RaffleReward = observer( color={Color.textGreen1} numberOfLines={1} i18n={I18N.raffleRewardPrize} - i18params={{islm: budget, symbol: app.provider.denom}} + i18params={{islm: budget, symbol: Provider.selectedProvider.denom}} /> diff --git a/src/components/settings/settings-account-detail/settings-account-detail.tsx b/src/components/settings/settings-account-detail/settings-account-detail.tsx index 0d961db8e..dac3a0e79 100644 --- a/src/components/settings/settings-account-detail/settings-account-detail.tsx +++ b/src/components/settings/settings-account-detail/settings-account-detail.tsx @@ -21,12 +21,12 @@ import { Text, TextVariant, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {AddressUtils} from '@app/helpers/address-utils'; import {Feature, isFeatureEnabled} from '@app/helpers/is-feature-enabled'; import {useCalculatedDimensionsValue} from '@app/hooks/use-calculated-dimensions-value'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Wallet} from '@app/models/wallet'; import {sendNotification} from '@app/services'; import {WalletType} from '@app/types'; @@ -122,7 +122,7 @@ export const SettingsAccountDetail = observer( - {app.provider.config.isBech32Enabled && ( + {Provider.selectedProvider.config.isBech32Enabled && ( , + Partial, 'ethChainId' | 'id' > & { isChanged: boolean; @@ -45,9 +45,9 @@ export type SettingsProviderEditData = Omit< }; export type SettingsProviderEditProps = { - provider: Partial | null; + provider: Partial | null; buttonType?: 'save' | 'del'; - onSubmit: (provider: Partial) => void; + onSubmit: (provider: Partial) => void; onDelete: () => void; onCancel: () => void; onSelect: () => void; diff --git a/src/components/settings/settings-providers/settings-providers-all-networks-row.tsx b/src/components/settings/settings-providers/settings-providers-all-networks-row.tsx new file mode 100644 index 000000000..5903f0816 --- /dev/null +++ b/src/components/settings/settings-providers/settings-providers-all-networks-row.tsx @@ -0,0 +1,59 @@ +import React from 'react'; + +import {TouchableWithoutFeedback, View} from 'react-native'; + +import {Color} from '@app/colors'; +import {DataContent, Icon, IconsName, Spacer} from '@app/components/ui'; +import {createTheme} from '@app/helpers'; +import {ALL_NETWORKS_ID, ProviderModel} from '@app/models/provider'; + +export type SettingsProvidersAllNetworksRowProps = { + item: ProviderModel; + providerId: string; + onPress: (providerId: string) => void; +}; +export const SettingsProvidersAllNetworksRow = ({ + item, + onPress, + providerId, +}: SettingsProvidersAllNetworksRowProps) => { + return ( + { + onPress(item.id); + }}> + + + + + + + + {providerId === ALL_NETWORKS_ID && ( + + )} + + + ); +}; + +const styles = createTheme({ + container: { + flexDirection: 'row', + alignItems: 'center', + }, + info: {justifyContent: 'space-between'}, + iconWrapper: { + width: 42, + height: 42, + backgroundColor: Color.bg3, + alignItems: 'center', + justifyContent: 'center', + borderRadius: 12, + }, + icon: {width: 28, height: 28}, +}); diff --git a/src/components/settings/settings-providers/settings-providers-row.tsx b/src/components/settings/settings-providers/settings-providers-row.tsx index c3451b2e6..a20c65fbd 100644 --- a/src/components/settings/settings-providers/settings-providers-row.tsx +++ b/src/components/settings/settings-providers/settings-providers-row.tsx @@ -5,10 +5,10 @@ import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'; import {Color} from '@app/colors'; import {ImageWrapper} from '@app/components/image-wrapper'; import {DataContent, Icon, Spacer} from '@app/components/ui'; -import {Provider} from '@app/models/provider'; +import {ProviderModel} from '@app/models/provider'; export type SettingsProvidersRowProps = { - item: Provider; + item: ProviderModel; providerId: string; onPress: (providerId: string) => void; }; diff --git a/src/components/settings/settings-providers/settings-providers.tsx b/src/components/settings/settings-providers/settings-providers.tsx index c9ecb87e5..54c105eaa 100644 --- a/src/components/settings/settings-providers/settings-providers.tsx +++ b/src/components/settings/settings-providers/settings-providers.tsx @@ -2,12 +2,12 @@ import React from 'react'; import {FlatList, StyleSheet} from 'react-native'; -import {Provider} from '@app/models/provider'; +import {ProviderModel} from '@app/models/provider'; import {SettingsProvidersRow} from './settings-providers-row'; export type SettingsProvidersProps = { - providers: Provider[]; + providers: ProviderModel[]; providerId: string; onSelect: (providerId: string) => void; }; diff --git a/src/components/staking-delegate-finish/staking-delegate-finish.tsx b/src/components/staking-delegate-finish/staking-delegate-finish.tsx index 024134786..f982f3435 100644 --- a/src/components/staking-delegate-finish/staking-delegate-finish.tsx +++ b/src/components/staking-delegate-finish/staking-delegate-finish.tsx @@ -15,10 +15,10 @@ import { TextVariant, } from '@app/components/ui'; import {NetworkFee} from '@app/components/ui/network-fee'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {cleanNumber} from '@app/helpers/clean-number'; import {I18N} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Balance} from '@app/services/balance'; import {ValidatorItem} from '@app/types'; @@ -66,7 +66,7 @@ export const StakingDelegateFinish = observer( variant={TextVariant.t3} position={TextPosition.center} style={styles.sum}> - - {`${cleanNumber(amount)} ${app.provider.denom}`} + - {`${cleanNumber(amount)} ${Provider.selectedProvider.denom}`} { const transactionFee = useMemo( - () => (fee ? fee.max(FEE_AMOUNT) : Balance.Empty), + () => (fee ? fee.max(new Balance(FEE_AMOUNT)) : Balance.Empty), [fee], ); diff --git a/src/components/staking-delegate-preview/staking-delegate-preview.tsx b/src/components/staking-delegate-preview/staking-delegate-preview.tsx index d84405091..5907e2691 100644 --- a/src/components/staking-delegate-preview/staking-delegate-preview.tsx +++ b/src/components/staking-delegate-preview/staking-delegate-preview.tsx @@ -17,11 +17,11 @@ import { TextPosition, TextVariant, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {cleanNumber} from '@app/helpers/clean-number'; import {formatPercents} from '@app/helpers/format-percents'; import {I18N, getText} from '@app/i18n'; +import {Provider} from '@app/models/provider'; import {Balance} from '@app/services/balance'; import {ValidatorItem, ValidatorStatus} from '@app/types'; @@ -74,7 +74,7 @@ export const StakingDelegatePreview = observer( i18n={I18N.amount} i18params={{ amount: cleanNumber(amount), - symbol: app.provider.denom, + symbol: Provider.selectedProvider.denom, }} /> - - {`${cleanNumber(amount)} ${app.provider.denom}`} + - {`${cleanNumber(amount)} ${Provider.selectedProvider.denom}`} diff --git a/src/components/swap/swap.tsx b/src/components/swap/swap.tsx index 0ea20594a..e67059394 100644 --- a/src/components/swap/swap.tsx +++ b/src/components/swap/swap.tsx @@ -4,12 +4,12 @@ import {observer} from 'mobx-react'; import {View} from 'react-native'; import {Color} from '@app/colors'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {shortAddress} from '@app/helpers/short-address'; import {useSumAmount} from '@app/hooks'; import {I18N} from '@app/i18n'; import {Contracts} from '@app/models/contracts'; +import {Provider} from '@app/models/provider'; import {Wallet} from '@app/models/wallet'; import {Balance} from '@app/services/balance'; import { @@ -268,9 +268,10 @@ export const Swap = observer( {(isWrapTx || isUnwrapTx) && ( item.is_in_white_list && // FIXME: only erc20 tokens or native currency (ISLM) - (item.is_erc20 || item.symbol === app.provider.denom), + (item.is_erc20 || + item.symbol === Provider.selectedProvider.denom), )} tokensOnly={!!wallet} isLast={index === list.length - 1} diff --git a/src/components/transaction-confirmation/transaction-confirmation.tsx b/src/components/transaction-confirmation/transaction-confirmation.tsx index 419b1bf60..bf3953a4d 100644 --- a/src/components/transaction-confirmation/transaction-confirmation.tsx +++ b/src/components/transaction-confirmation/transaction-confirmation.tsx @@ -16,11 +16,11 @@ import { TextPosition, TextVariant, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme} from '@app/helpers'; import {I18N, getText} from '@app/i18n'; import {Contact} from '@app/models/contact'; import {Fee} from '@app/models/fee'; +import {Provider} from '@app/models/provider'; import {Balance} from '@app/services/balance'; import {BalanceData, IToken} from '@app/types'; import {splitAddress} from '@app/utils'; @@ -77,7 +77,7 @@ export const TransactionConfirmation = observer( // When sanding native token than calculation includes // amount + fee - availablebalance - if (amount.getSymbol() === app.provider.denom) { + if (amount.getSymbol() === Provider.selectedProvider.denom) { return ( fee.calculatedFees.expectedFee .operate(amount, 'add') @@ -179,7 +179,7 @@ export const TransactionConfirmation = observer( - {app.provider.name} + {Provider.selectedProvider.name} @@ -217,7 +217,7 @@ export const TransactionConfirmation = observer( position={TextPosition.center} color={Color.graphicRed1} i18n={I18N.transactionSumError} - i18params={{symbol: app.provider.weiDenom}} + i18params={{symbol: Provider.selectedProvider.weiDenom}} /> )} diff --git a/src/components/transaction-detail.tsx b/src/components/transaction-detail.tsx index 4ede79f1b..87c11a7dd 100644 --- a/src/components/transaction-detail.tsx +++ b/src/components/transaction-detail.tsx @@ -11,7 +11,7 @@ import {AddressUtils} from '@app/helpers/address-utils'; import {useCalculatedDimensionsValue} from '@app/hooks/use-calculated-dimensions-value'; import {I18N, getText} from '@app/i18n'; import {Contracts} from '@app/models/contracts'; -import {Provider} from '@app/models/provider'; +import {ProviderModel} from '@app/models/provider'; import {Transaction} from '@app/models/transaction'; import {Balance} from '@app/services/balance'; import {IndexerTxMsgType} from '@app/types'; @@ -21,7 +21,7 @@ import {ImageWrapper} from './image-wrapper'; type TransactionDetailProps = { tx: Transaction; - provider: Provider | null; + provider: ProviderModel | null; splitted: string[]; timestamp: string; fee: Balance; diff --git a/src/components/transaction-finish.tsx b/src/components/transaction-finish.tsx index 800bf4927..9810c7db2 100644 --- a/src/components/transaction-finish.tsx +++ b/src/components/transaction-finish.tsx @@ -19,11 +19,11 @@ import { TextPosition, TextVariant, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme, openURL} from '@app/helpers'; import {I18N} from '@app/i18n'; import {Contact} from '@app/models/contact'; import {Fee} from '@app/models/fee'; +import {Provider} from '@app/models/provider'; import {sendNotification} from '@app/services'; import {Balance} from '@app/services/balance'; import {IToken, TransactionResponse} from '@app/types'; @@ -56,7 +56,9 @@ export const TransactionFinish = observer( }: TransactionFinishProps) => { const name = token?.name || contact?.name; const onPressHash = async () => { - const url = app.provider.getTxExplorerUrl(transaction?.hash!); + const url = Provider.selectedProvider.getTxExplorerUrl( + transaction?.hash!, + ); await openURL(url); }; @@ -74,15 +76,15 @@ export const TransactionFinish = observer( return new Balance( (transaction as TransactionResponse)?.value._hex ?? 0, undefined, - token.symbol ?? app.provider.denom, + token.symbol ?? Provider.selectedProvider.denom, ); } return new Balance( transaction?.value ?? 0, undefined, - token.symbol ?? app.provider.denom, + token.symbol ?? Provider.selectedProvider.denom, ); - }, [transaction, token, amount, app.provider.denom]); + }, [transaction, token, amount, Provider.selectedProvider.denom]); return ( @@ -118,7 +120,7 @@ export const TransactionFinish = observer( position={TextPosition.center} style={styles.address}> {name} - {STRINGS.NBSP}({token.symbol || app.provider.denom}) + {STRINGS.NBSP}({token.symbol || Provider.selectedProvider.denom}) )} - {app.provider.name} + {Provider.selectedProvider.name} - {`${STRINGS.NBSP}(${app.provider.denom})`} + {`${STRINGS.NBSP}(${Provider.selectedProvider.denom})`} diff --git a/src/components/transaction-nft-finish.tsx b/src/components/transaction-nft-finish.tsx index a44f52257..59703a4d4 100644 --- a/src/components/transaction-nft-finish.tsx +++ b/src/components/transaction-nft-finish.tsx @@ -1,6 +1,7 @@ import React, {useCallback} from 'react'; import Clipboard from '@react-native-clipboard/clipboard'; +import {observer} from 'mobx-react'; import {View} from 'react-native'; import {Color} from '@app/colors'; @@ -17,13 +18,13 @@ import { TextPosition, TextVariant, } from '@app/components/ui'; -import {app} from '@app/contexts'; import {createTheme, openURL} from '@app/helpers'; import {useNftImage} from '@app/hooks/nft'; import {I18N} from '@app/i18n'; import {Contact} from '@app/models/contact'; import {Fee} from '@app/models/fee'; import {NftItem} from '@app/models/nft'; +import {Provider} from '@app/models/provider'; import {sendNotification} from '@app/services'; import {TransactionResponse} from '@app/types'; import {STRINGS} from '@app/variables/common'; @@ -40,139 +41,143 @@ type TransactionFinishProps = { fee: Fee; }; -export const TransactionNftFinish = ({ - transaction, - item, - onSubmit, - onPressContact, - contact, - fee, -}: TransactionFinishProps) => { - const onPressHash = async () => { - const url = app.provider.getTxExplorerUrl(transaction?.hash!); - await openURL(url); - }; +export const TransactionNftFinish = observer( + ({ + transaction, + item, + onSubmit, + onPressContact, + contact, + fee, + }: TransactionFinishProps) => { + const onPressHash = async () => { + const url = Provider.selectedProvider.getTxExplorerUrl( + transaction?.hash!, + ); + await openURL(url); + }; - const onPressToAddress = useCallback(() => { - Clipboard.setString(transaction?.to ?? ''); - sendNotification(I18N.notificationCopied); - }, [transaction]); + const onPressToAddress = useCallback(() => { + Clipboard.setString(transaction?.to ?? ''); + sendNotification(I18N.notificationCopied); + }, [transaction]); - const nftImageUri = useNftImage( - typeof item.cached_url === 'string' - ? item.cached_url - : item.metadata?.image, - ); + const nftImageUri = useNftImage( + typeof item.cached_url === 'string' + ? item.cached_url + : item.metadata?.image, + ); - return ( - - - + + + + + - - - - - {item.name} - - - - {contact?.name && ( + + {item.name} + + + + {contact?.name && ( + + {contact.name} + + )} - {contact.name} + {transaction?.to} - )} - - {transaction?.to} - - + - + - - - {app.provider.name} - - - {`${STRINGS.NBSP}(${app.provider.denom})`} - - + + + {Provider.selectedProvider.name} + + + {`${STRINGS.NBSP}(${Provider.selectedProvider.denom})`} + + - - - - {contact ? ( - + + + {contact ? ( + + ) : ( + + )} + - ) : ( + + - )} - - - - - - - -