Skip to content

Commit

Permalink
Merge pull request #2819 from superhero-com/feat/extract-custom-token…
Browse files Browse the repository at this point in the history
…s-from-token-balances

feat: extract custom tokens from token balances
  • Loading branch information
martinkaintas authored Mar 13, 2024
2 parents 29819d5 + 6a0670b commit 5bb0cf3
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
48 changes: 43 additions & 5 deletions src/composables/fungibleTokens.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-param-reassign */

import { watch } from 'vue';
import { computed, watch } from 'vue';
import BigNumber from 'bignumber.js';
import { Encoding } from '@aeternity/aepp-sdk';
import { toShiftedBigNumber } from '@/utils';
Expand All @@ -22,6 +22,7 @@ import { ProtocolAdapterFactory } from '@/lib/ProtocolAdapterFactory';
import FungibleTokenFullInterfaceACI from '@/protocols/aeternity/aci/FungibleTokenFullInterfaceACI.json';
import { aettosToAe, categorizeContractCallTxObject } from '@/protocols/aeternity/helpers';

import { uniqBy } from 'lodash-es';
import { useAccounts } from './accounts';
import { useAeSdk } from './aeSdk';
import { useTippingContracts } from './tippingContracts';
Expand All @@ -33,9 +34,10 @@ let composableInitialized = false;

/**
* List of all fungible tokens available on user's protocols.
* Does not include custom tokens extracted from user's token balances.
* As this list is quite big (hundreds of items) it requires processing optimizations.
*/
const tokensAvailable = useStorageRef<ProtocolRecord<AssetList>>(
const defaultTokensAvailable = useStorageRef<ProtocolRecord<AssetList>>(
{},
STORAGE_KEYS.fungibleTokenList,
);
Expand All @@ -48,6 +50,41 @@ const tokenBalances = useStorageRef<ITokenBalance[]>(
STORAGE_KEYS.fungibleTokenBalances,
);

/**
* List of all fungible tokens available on user's protocols.
* Includes tokens from the user's account that are not on the main list.
*/
const tokensAvailable = computed((): ProtocolRecord<AssetList> => {
const uniqueTokens: IToken[] = uniqBy(tokenBalances.value, 'contractId')
.map((tokenBalance) => ({
contractId: tokenBalance.contractId,
protocol: tokenBalance.protocol,
name: tokenBalance?.name!,
symbol: tokenBalance?.symbol!,
}));

const customTokensAvailable = uniqueTokens.reduce((customTokens, token) => {
const { contractId, protocol } = token;
if (!customTokens[protocol]) {
customTokens[protocol] = {} as AssetList;
}
if (!defaultTokensAvailable?.value?.[protocol]?.[contractId]) {
customTokens[protocol]![contractId] = token;
}
return customTokens;
}, {} as typeof tokensAvailable.value);

return Object.values(PROTOCOLS).reduce(
(allTokens, protocol) => {
allTokens[protocol] = {
...defaultTokensAvailable.value[protocol],
...customTokensAvailable[protocol],
};
return allTokens;
}, {} as typeof defaultTokensAvailable.value,
);
});

function getProtocolAvailableTokens(protocol: Protocol): AssetList {
return tokensAvailable.value[protocol] || {} as AssetList;
}
Expand Down Expand Up @@ -92,7 +129,7 @@ export function useFungibleTokens() {
const tokens: IToken[] = (await Promise.all(tokensFetchPromises)).map(
(protocolTokens, index) => (
protocolTokens
|| Object.values(tokensAvailable.value[protocolsInUse.value[index]] || {})
|| Object.values(defaultTokensAvailable.value[protocolsInUse.value[index]] || {})
),
).flat();

Expand All @@ -102,14 +139,14 @@ export function useFungibleTokens() {
return;
}

tokensAvailable.value = tokens.reduce((accumulator, token) => {
defaultTokensAvailable.value = tokens.reduce((accumulator, token) => {
const { contractId, protocol } = token;
if (!accumulator[protocol]) {
accumulator[protocol] = {} as AssetList;
}
accumulator[protocol]![contractId] = token;
return accumulator;
}, {} as typeof tokensAvailable.value);
}, {} as typeof defaultTokensAvailable.value);
}

async function loadTokenBalances() {
Expand Down Expand Up @@ -147,6 +184,7 @@ export function useFungibleTokens() {
async ([address, promise]) => await promise || cachedTokenBalancesByAddress[address] || [],
),
)).flat();

areTokenBalancesUpdating = false;
}

Expand Down
9 changes: 8 additions & 1 deletion src/protocols/ethereum/libs/EthplorerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,20 @@ export class EthplorerService {

return tokens.map(({
rawBalance,
tokenInfo: { address: contractId, decimals },
tokenInfo: {
address: contractId,
decimals,
name,
symbol,
},
}: any): ITokenBalance => ({
address,
amount: rawBalance,
contractId: toEthChecksumAddress(contractId),
convertedBalance: +toShiftedBigNumber(rawBalance, -decimals).toFixed(2),
decimals,
symbol,
name,
protocol: PROTOCOLS.ethereum,
})) || [];
}
Expand Down
3 changes: 3 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ export interface ITokenBalance {
/** Amount of the token that is owned */
convertedBalance?: number;
protocol: Protocol;
// Allow setting symbol and name so that we can extract custom tokens from balance data
symbol?: string;
name?: string;
}

/**
Expand Down

0 comments on commit 5bb0cf3

Please sign in to comment.