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 ca91a4c4c..3a1165179 100644 --- a/src/components/json-rpc-sign/json-rpc-common-transaction.tsx +++ b/src/components/json-rpc-sign/json-rpc-common-transaction.tsx @@ -186,7 +186,7 @@ export const JsonRpcCommonTransaction = ({ + color={Color.textGreen1}> {Contracts.getById(parsedInput?.args?.[0])?.name ?? ''} {STRINGS.NBSP} {shortAddress(parsedInput?.args?.[0], '•', true)} 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 3078cba65..f53e2adb1 100644 --- a/src/components/json-rpc-sign/json-rpc-swap-transaction.tsx +++ b/src/components/json-rpc-sign/json-rpc-swap-transaction.tsx @@ -414,7 +414,7 @@ export const JsonRpcSwapTransaction = observer( + color={Color.textGreen1}> {Contracts.getById(tx?.to!)?.name} {STRINGS.NBSP} {shortAddress(tx?.to!, '•', true)} diff --git a/src/components/json-viewer.tsx b/src/components/json-viewer.tsx index d36a210e3..d814a4d88 100644 --- a/src/components/json-viewer.tsx +++ b/src/components/json-viewer.tsx @@ -33,6 +33,7 @@ const CustomNode = ({value}: {value: any}) => { "{part0} @@ -43,7 +44,11 @@ const CustomNode = ({value}: {value: any}) => { ); } - return {value}; + return ( + + {value} + + ); }; export const JsonViewer = ({ diff --git a/src/models/tokens.ts b/src/models/tokens.ts index 3eb2efa6a..4a891a985 100644 --- a/src/models/tokens.ts +++ b/src/models/tokens.ts @@ -13,6 +13,7 @@ import {storage} from '@app/services/mmkv'; import { AddressType, HaqqCosmosAddress, + HaqqEthereumAddress, IContract, IToken, IndexerToken, @@ -109,7 +110,7 @@ class TokensStore implements MobXStore { } else { this.data = { ...this.data, - [AddressUtils.toHaqq(id)]: params, + [AddressUtils.toEth(id)]: params, }; } @@ -127,7 +128,7 @@ class TokensStore implements MobXStore { const newData = { ...this.data, }; - delete newData[AddressUtils.toHaqq(id)]; + delete newData[AddressUtils.toEth(id)]; this.data = newData; return true; @@ -163,7 +164,7 @@ class TokensStore implements MobXStore { } getById(id: string) { - return this.data[AddressUtils.toHaqq(id)]; + return this.data[AddressUtils.toEth(id)]; } update(id: string | undefined, item: Omit) { @@ -179,7 +180,7 @@ class TokensStore implements MobXStore { this.data = { ...this.data, - [AddressUtils.toHaqq(id)]: { + [AddressUtils.toEth(id)]: { ...itemToUpdate, ...item, value: updatedValue, @@ -195,6 +196,7 @@ class TokensStore implements MobXStore { runInAction(() => { this._isLoading = true; + this.tokens = {}; }); const wallets = Wallet.getAll(); @@ -202,24 +204,27 @@ class TokensStore implements MobXStore { const updates = await Indexer.instance.updates(accounts, this.lastUpdate); const addressesMap = new Map( - updates.addresses.map(address => [address.id, address]), + updates.addresses.map(address => [ + AddressUtils.toEth(address.id), + address, + ]), ); - runInAction(() => { - this.tokens = {}; - }); + const _tokens = {} as Record; + const _data = {} as Record; - for (const t of updates.tokens) { + for await (const t of updates.tokens) { try { const isPositive = new Balance(t.value).isPositive(); if (!isPositive) { continue; } + const contractAddress = AddressUtils.toEth(t.contract); const contract = - addressesMap.get(t.contract) || - this.getContract(t.contract) || - (await Whitelist.verifyAddress(t.contract)); + addressesMap.get(contractAddress) || + this.getContract(contractAddress) || + (await Whitelist.verifyAddress(contractAddress)); if (!contract) { Logger.error( @@ -235,8 +240,8 @@ class TokensStore implements MobXStore { contract_updated_at: contract.updated_at, value: new Balance( t.value, - contract.decimals || app.provider.decimals, - contract.symbol || app.provider.denom, + contract.decimals ?? app.provider.decimals, + contract.symbol ?? app.provider.denom, ), decimals: contract.decimals, is_erc20: contract.is_erc20, @@ -254,15 +259,14 @@ class TokensStore implements MobXStore { const walletAddress = AddressUtils.toEth(t.address); - runInAction(() => { - if (!this.tokens[walletAddress]?.length) { - this.tokens[walletAddress] = [ - this.generateNativeToken(Wallet.getById(walletAddress)!), - ]; - } + if (!_tokens[walletAddress]?.length) { + _tokens[walletAddress] = [ + this.generateNativeToken(Wallet.getById(walletAddress)!), + ]; + } - this.tokens[walletAddress].push(token); - }); + _tokens[walletAddress].push(token); + _data[AddressUtils.toEth(token.id)] = token; } catch (e) { Logger.error( 'TokensStore.fetchTokens', @@ -271,7 +275,14 @@ class TokensStore implements MobXStore { } } - this._isLoading = false; + runInAction(() => { + this.tokens = _tokens; + this.data = { + ...this.data, + ..._data, + }; + this._isLoading = false; + }); }); public generateNativeToken = (wallet: Wallet): IToken => { @@ -341,7 +352,7 @@ class TokensStore implements MobXStore { const contractFromCache = this.getContract(token.contract); const result: IToken = { - id: contractFromCache.id, + id: AddressUtils.toHaqq(contractFromCache.id), contract_created_at: contractFromCache.created_at, contract_updated_at: contractFromCache.updated_at, value: new Balance( @@ -374,7 +385,7 @@ class TokensStore implements MobXStore { Contracts.create(contract.id, contract); }; - private getContract = (id: HaqqCosmosAddress) => { + private getContract = (id: HaqqCosmosAddress | HaqqEthereumAddress) => { return Contracts.getById(id); }; diff --git a/src/screens/SwapStack/swap-screen.tsx b/src/screens/SwapStack/swap-screen.tsx index fb770ed68..7b05ea3c8 100644 --- a/src/screens/SwapStack/swap-screen.tsx +++ b/src/screens/SwapStack/swap-screen.tsx @@ -66,12 +66,8 @@ const getMinAmountForDecimals = (d: number | null, symbol: string | null) => { if (!d) { return MIN_SWAP_AMOUNT; } - const zero = Array.from({length: d - 1}) - .fill('0') - .join(''); - const min = `0.${zero}1`; - const amountBN = ethers.utils.parseUnits(min, d); - return new Balance(amountBN, d, symbol || app.provider.denom); + + return new Balance(Number(`0.${'0'.repeat(d! - 1)}1`), d, symbol!); }; export const SwapScreen = observer(() => { @@ -286,7 +282,7 @@ export const SwapScreen = observer(() => { awaitForEventDone(Events.onBalanceSync), ]); } - await refreshTokenBalances(currentWallet.address, tokenIn); + await refreshTokenBalances(currentWallet.address, t0Available); if (isWrapTx || isUnwrapTx) { amountsOut.setAmount(amountsIn.amount); @@ -443,7 +439,10 @@ export const SwapScreen = observer(() => { closeOnSelect: true, renderCell: ( // eslint-disable-next-line @typescript-eslint/no-shadow - value: AwaitValue<{wallet: Wallet; tokens: IToken[]}>, + value: AwaitValue<{ + wallet: Wallet; + tokens: (IToken & {tag: string})[]; + }>, _, onPress, ) => { @@ -462,11 +461,8 @@ export const SwapScreen = observer(() => { return { ...t, value: - Token.tokens[ - AddressUtils.toEth(value?.wallet?.address) - // @ts-ignore - ].find(c => c.id === t.tag?.split?.('_')[1])?.value ?? - new Balance(0, 0, t?.symbol!), + tokens.find(c => c.id === t.tag?.split?.('_')[1]) + ?.value ?? new Balance(0, 0, t?.symbol!), }; })} onPressToken={(w, newValue, idx) => { @@ -523,7 +519,7 @@ export const SwapScreen = observer(() => { const refreshTokenBalances = async ( wallet = currentWallet.address, - t0 = tokenIn, + t0 = t0Available, ) => { if (!t0 || !wallet) { return {}; @@ -532,13 +528,13 @@ export const SwapScreen = observer(() => { const tokenValue = // @ts-ignore t0.value || - Token.tokens?.[wallet]?.find(t => AddressUtils.equals(t.id, t0.id!)) + Token.tokens?.[wallet]?.find(t => AddressUtils.equals(t.id, tokenIn?.id!)) ?.value; const availableIslm = app.getAvailableBalance(wallet); - const symbol = t0.symbol || app.provider.denom; - const isNativeCurrency = symbol.toUpperCase() === app.provider.denom; - const decimals = t0.decimals || app.provider.decimals; + const symbol = t0.getSymbol() || app.provider.denom; + const isNativeCurrency = symbol === app.provider.denom; + const decimals = t0.getPrecission() || app.provider.decimals; const zeroBalance = new Balance('0x0', decimals, symbol); const value = new Balance( (isNativeCurrency ? availableIslm : tokenValue) || zeroBalance, @@ -597,7 +593,7 @@ export const SwapScreen = observer(() => { ); setCurrentRoute(route! || filteredRoutes[0]); } - await refreshTokenBalances(wallet.address, token); + await refreshTokenBalances(wallet.address, t0Available); amountsIn.setMin(); return await estimate(); } catch (err) { @@ -642,7 +638,7 @@ export const SwapScreen = observer(() => { ); setCurrentRoute(route! || filteredRoutes[0]); } - await refreshTokenBalances(wallet.address, tokenIn); + await refreshTokenBalances(wallet.address, t0Available); return await estimate(); } catch (err) { Logger.error(err, 'onPressChangeTokenOut'); @@ -962,11 +958,12 @@ export const SwapScreen = observer(() => { const onPressMax = async () => { Keyboard.dismiss(); vibrate(HapticEffects.impactLight); - const {value} = await refreshTokenBalances(currentWallet.address, tokenIn); - const balance = value || t0Available; + await refreshTokenBalances(currentWallet.address, t0Available); + amountsIn.setAmount( - balance.toBalanceString('auto', tokenIn?.decimals!, false), + t0Available.toBalanceString('auto', tokenIn?.decimals!, false), ); + await estimate(); }; @@ -979,7 +976,7 @@ export const SwapScreen = observer(() => { wallets: walletsWithBalances?.length ? walletsWithBalances : wallets, initialAddress: currentWallet.address, }); - await refreshTokenBalances(address as HaqqEthereumAddress, tokenIn); + await refreshTokenBalances(address as HaqqEthereumAddress, t0Available); setCurrentWallet(() => Wallet.getById(address)!); }, [currentWallet, refreshTokenBalances, tokenIn]); @@ -1017,7 +1014,7 @@ export const SwapScreen = observer(() => { useEffect(() => { if (currentRoute) { logger.log('useEffect estimate()'); - refreshTokenBalances(currentWallet.address, tokenIn).then(() => + refreshTokenBalances(currentWallet.address, t0Available).then(() => estimate(), ); } diff --git a/src/screens/settings-developer-tools.tsx b/src/screens/settings-developer-tools.tsx index 7986b1838..d7b577cf7 100644 --- a/src/screens/settings-developer-tools.tsx +++ b/src/screens/settings-developer-tools.tsx @@ -1,14 +1,18 @@ -import React, {useCallback, useMemo, useState} from 'react'; +import React, {useCallback, useEffect, useMemo, useState} from 'react'; import Clipboard from '@react-native-clipboard/clipboard'; import CookieManager from '@react-native-cookies/cookies'; import {observer} from 'mobx-react'; -import {Alert, ScrollView} from 'react-native'; +import {Alert, ScrollView, StyleSheet, View} from 'react-native'; +import {Color} from '@app/colors'; import {SettingsButton} from '@app/components/home-settings/settings-button'; +import {JsonViewer} from '@app/components/json-viewer'; import { Button, + ButtonSize, ButtonVariant, + First, IconsName, Input, Spacer, @@ -21,7 +25,9 @@ import {awaitForWallet, createTheme, hideModal, showModal} from '@app/helpers'; import {AddressUtils} from '@app/helpers/address-utils'; import {awaitForJsonRpcSign} from '@app/helpers/await-for-json-rpc-sign'; import {awaitForProvider} from '@app/helpers/await-for-provider'; +import {AppInfo, getAppInfo} from '@app/helpers/get-app-info'; import {Whitelist} from '@app/helpers/whitelist'; +import {useLayoutAnimation} from '@app/hooks/use-layout-animation'; import {I18N} from '@app/i18n'; import {Language} from '@app/models/language'; import {Provider} from '@app/models/provider'; @@ -51,6 +57,7 @@ const Title = ({text = ''}) => ( ); export const SettingsDeveloperTools = observer(() => { + const {animate} = useLayoutAnimation(); const [wc, setWc] = useState(''); const [rawSignData, setRawSignData] = useState(''); const [signData, setSignData] = useState(); @@ -58,6 +65,8 @@ export const SettingsDeveloperTools = observer(() => { const [browserUrl, setBrowserUrl] = useState(''); const [convertAddress, setConvertAddress] = useState(''); const [verifyAddress, setVerifyAddress] = useState(''); + const [appInfo, setAppInfo] = useState(); + const [isAppInfoHidden, setAppInfoHidden] = useState(true); const isValidConvertAddress = useMemo( () => AddressUtils.isValidAddress(convertAddress), @@ -74,6 +83,16 @@ export const SettingsDeveloperTools = observer(() => { navigator.goBack(); }, []); + const handleShowJsonViewer = useCallback(() => { + animate(); + setAppInfoHidden(false); + }, [animate]); + + const handleHideJsonViewer = useCallback(() => { + animate(); + setAppInfoHidden(true); + }, [animate]); + const onPressWc = () => { app.emit(Events.onWalletConnectUri, wc); }; @@ -111,8 +130,42 @@ export const SettingsDeveloperTools = observer(() => { toastMessage('Cookie cleared'); }; + useEffect(() => { + getAppInfo().then(setAppInfo); + }); + return ( + + + {isAppInfoHidden && ( +