Skip to content

Commit

Permalink
fix: fetch ERC20 token contract info for transactions list when token…
Browse files Browse the repository at this point in the history
… balance is zero (#2192)
  • Loading branch information
iGroza authored Nov 11, 2024
1 parent 2c641a0 commit 98910ab
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 39 deletions.
79 changes: 68 additions & 11 deletions src/models/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class TokensStore implements MobXStore<IToken> {
* @value IToken
*/
data: Record<string, IToken> = {};
fetchedUnknownTokens: Record<string, boolean> = {};
/**
* Indexer response with token info
* @key Wallet address
Expand All @@ -51,6 +52,8 @@ class TokensStore implements MobXStore<IToken> {
properties: [
// https://github.com/quarrant/mobx-persist-store/issues/97
// @ts-ignore
'fetchedUnknownTokens',
// @ts-ignore
'contracts',
{
key: 'tokens',
Expand Down Expand Up @@ -177,17 +180,68 @@ class TokensStore implements MobXStore<IToken> {
}

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<IToken, 'id'>) {
if (!id) {
return false;
Expand All @@ -199,14 +253,17 @@ class TokensStore implements MobXStore<IToken> {

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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/widgets/tokens-widget/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
54 changes: 26 additions & 28 deletions src/widgets/transactions-widget/transactions-widget.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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 (
<>
<ShadowCard onPress={onPress} style={styles.wrapper}>
<WidgetHeader title={getText(I18N.transactionWidgetShortTitle)} />
<Spacer height={8} />
{lastTransactions.map(item => {
return (
<TransactionRow
key={`${item.id}:${item.hash}:${item.msg.type}`}
item={item}
addresses={addressList}
onPress={onRowPress}
/>
);
})}
</ShadowCard>
</>
);
};
export const TransactionsWidget = observer(
({lastTransactions, addressList, onPress, onRowPress}: Props) => {
if (lastTransactions.length === 0) {
return <></>;
}
return (
<>
<ShadowCard onPress={onPress} style={styles.wrapper}>
<WidgetHeader title={getText(I18N.transactionWidgetShortTitle)} />
<Spacer height={8} />
{lastTransactions.map(item => {
return (
<TransactionRow
key={`${item.id}:${item.hash}:${item.msg.type}`}
item={item}
addresses={addressList}
onPress={onRowPress}
/>
);
})}
</ShadowCard>
</>
);
},
);

const styles = StyleSheet.create({
wrapper: {paddingHorizontal: 16},
Expand Down

0 comments on commit 98910ab

Please sign in to comment.