diff --git a/src/models/tokens.ts b/src/models/tokens.ts index d8004bf53..a70ef8329 100644 --- a/src/models/tokens.ts +++ b/src/models/tokens.ts @@ -34,6 +34,7 @@ class TokensStore implements MobXStore { * @value IToken */ data: Record = {}; + fetchedUnknownTokens: Record = {}; /** * Indexer response with token info * @key Wallet address @@ -51,6 +52,8 @@ class TokensStore implements MobXStore { properties: [ // https://github.com/quarrant/mobx-persist-store/issues/97 // @ts-ignore + 'fetchedUnknownTokens', + // @ts-ignore 'contracts', { key: 'tokens', @@ -177,17 +180,68 @@ class TokensStore implements MobXStore { } getById(id: string) { - const token = this.data[AddressUtils.toEth(id)]; + let token = this.data[AddressUtils.toEth(id)]; if (!token) { - return Object.values(this.tokens) + token = Object.values(this.tokens) .flat() - .find(t => t.id === id); + .find(t => t.id === id)!; + } + + if (!token) { + this._safeLoadUnknownToken(id); } return token; } + /** + * Load unknown token by id + * @param id - token id + */ + private _safeLoadUnknownToken = createAsyncTask(async (id: string) => { + try { + if (this.fetchedUnknownTokens[id]) { + return; + } + + const headers = Indexer.instance.getProvidersHeader([id]); + const contracts = await Indexer.instance.getAddresses(headers); + const tokensForAnyChains = Object.entries(contracts).flatMap( + ([chain_id, v]) => v.map(c => ({...c, chain_id: Number(chain_id)})), + ) as (IContract & {chain_id: number})[]; + + runInAction(() => { + this.fetchedUnknownTokens[id] = true; + }); + + // find token with name, symbol, decimals and is_erc20 + const token = tokensForAnyChains?.find( + t => t.name && t.symbol && t.decimals && t.is_erc20, + ); + + if (token) { + runInAction(() => { + this.data[AddressUtils.toEth(token.id)] = { + ...token, + contract_created_at: token.created_at, + contract_updated_at: token.updated_at, + value: new Balance('0x0', token.decimals!, token.symbol!), + chain_id: token.chain_id!, + image: token.icon + ? {uri: token.icon} + : require('@assets/images/empty-icon.png'), + }; + }); + } + } catch (e) { + Logger.error('TokensStore: _safeLoadUnknownToken: error', { + error: e, + id, + }); + } + }); + update(id: string | undefined, item: Omit) { if (!id) { return false; @@ -199,14 +253,17 @@ class TokensStore implements MobXStore { const updatedValue = itemToUpdate.value.operate(item.value, 'add'); - this.data = { - ...this.data, - [AddressUtils.toEth(id)]: { - ...itemToUpdate, - ...item, - value: updatedValue, - }, - }; + runInAction(() => { + this.data = { + ...this.data, + [AddressUtils.toEth(id)]: { + ...itemToUpdate, + ...item, + value: updatedValue, + }, + }; + }); + return true; } diff --git a/src/widgets/tokens-widget/index.tsx b/src/widgets/tokens-widget/index.tsx index 7e5e5a974..725d0e819 100644 --- a/src/widgets/tokens-widget/index.tsx +++ b/src/widgets/tokens-widget/index.tsx @@ -44,6 +44,8 @@ export const TokensWidgetWrapper = observer(() => { return Object.values(cache); }, [tokens]); + Logger.log('tokens', JSON.stringify(tokens, null, 2)); + if (tokens.length === 0) { return null; } diff --git a/src/widgets/transactions-widget/transactions-widget.tsx b/src/widgets/transactions-widget/transactions-widget.tsx index 5dc1336c7..beafcda34 100644 --- a/src/widgets/transactions-widget/transactions-widget.tsx +++ b/src/widgets/transactions-widget/transactions-widget.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import {observer} from 'mobx-react'; import {StyleSheet} from 'react-native'; import {TransactionRow} from '@app/components/transaction-list/transaction-row'; @@ -17,34 +18,31 @@ type Props = { onRowPress(tx: Transaction): void; }; -export const TransactionsWidget = ({ - lastTransactions, - addressList, - onPress, - onRowPress, -}: Props) => { - if (lastTransactions.length === 0) { - return null; - } - return ( - <> - - - - {lastTransactions.map(item => { - return ( - - ); - })} - - - ); -}; +export const TransactionsWidget = observer( + ({lastTransactions, addressList, onPress, onRowPress}: Props) => { + if (lastTransactions.length === 0) { + return <>; + } + return ( + <> + + + + {lastTransactions.map(item => { + return ( + + ); + })} + + + ); + }, +); const styles = StyleSheet.create({ wrapper: {paddingHorizontal: 16},