Skip to content

Commit e3a2e51

Browse files
committed
feat(assets-controller): refactor getAsset
1 parent 89c1412 commit e3a2e51

1 file changed

Lines changed: 84 additions & 57 deletions

File tree

packages/assets-controller/src/AssetsController.ts

Lines changed: 84 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,15 +1814,9 @@ export class AssetsController extends BaseController<
18141814
);
18151815
}
18161816

1817-
const chainId = extractChainId(normalizedAssetId);
1818-
1819-
const assets = this.#getAssetsFromState(
1820-
[{ id: accountId }],
1821-
[chainId],
1822-
['fungible'],
1823-
);
1824-
1825-
return assets[accountId]?.[normalizedAssetId];
1817+
return this.#getAssetFromState(accountId, normalizedAssetId, {
1818+
assetTypeSet: new Set(['fungible']),
1819+
});
18261820
}
18271821

18281822
async getAssetsPrice(
@@ -2762,70 +2756,103 @@ export class AssetsController extends BaseController<
27622756

27632757
const accountBalances = this.state.assetsBalance[account.id] ?? {};
27642758

2765-
for (const [assetId, balance] of Object.entries(accountBalances)) {
2759+
for (const assetId of Object.keys(accountBalances)) {
27662760
const typedAssetId = assetId as Caip19AssetId;
27672761

2768-
const metadataRaw = this.state.assetsInfo[typedAssetId];
2762+
const asset = this.#getAssetFromState(account.id, typedAssetId, {
2763+
chainIdSet,
2764+
assetTypeSet,
2765+
});
27692766

2770-
// Skip assets without metadata
2771-
if (!metadataRaw) {
2772-
continue;
2767+
if (asset) {
2768+
result[account.id][typedAssetId] = asset;
27732769
}
2770+
}
2771+
}
27742772

2775-
const metadata = metadataRaw;
2773+
return result;
2774+
}
27762775

2777-
// Skip hidden assets (assetPreferences)
2778-
const prefs = this.state.assetPreferences[typedAssetId];
2779-
if (prefs?.hidden) {
2780-
continue;
2781-
}
2776+
/**
2777+
* Compose a single combined `Asset` (balance + metadata + price + computed
2778+
* `fiatValue`) for an account/asset pair directly from controller state,
2779+
* applying the same filtering rules as `#getAssetsFromState`.
2780+
*
2781+
* @param accountId - The account ID (`InternalAccount.id`).
2782+
* @param assetId - The normalized CAIP-19 asset ID.
2783+
* @param filters - Optional filters applied before composing the asset.
2784+
* @param filters.chainIdSet - When provided, the asset's chain must be in this set.
2785+
* @param filters.assetTypeSet - When provided, the asset's type must be in this set.
2786+
* @returns The combined `Asset`, or `undefined` when the asset is missing a
2787+
* balance/metadata, is hidden/filtered out, or fails a provided filter.
2788+
*/
2789+
#getAssetFromState(
2790+
accountId: AccountId,
2791+
assetId: Caip19AssetId,
2792+
filters?: {
2793+
chainIdSet?: Set<ChainId>;
2794+
assetTypeSet?: Set<AssetType>;
2795+
},
2796+
): Asset | undefined {
2797+
const balance = this.state.assetsBalance[accountId]?.[assetId];
27822798

2783-
const assetChainId = extractChainId(typedAssetId);
2799+
// Skip assets without a balance entry
2800+
if (!balance) {
2801+
return undefined;
2802+
}
27842803

2785-
// Skip native tokens on Tempo networks
2786-
if (this.#shouldHideNativeToken(assetChainId, metadata)) {
2787-
continue;
2788-
}
2804+
const metadata = this.state.assetsInfo[assetId];
27892805

2790-
if (!chainIdSet.has(assetChainId)) {
2791-
continue;
2792-
}
2806+
// Skip assets without metadata
2807+
if (!metadata) {
2808+
return undefined;
2809+
}
27932810

2794-
// Filter by asset type
2795-
const tokenAssetType = this.#tokenStandardToAssetType(metadata.type);
2796-
if (!assetTypeSet.has(tokenAssetType)) {
2797-
continue;
2798-
}
2811+
// Skip hidden assets (assetPreferences)
2812+
const prefs = this.state.assetPreferences[assetId];
2813+
if (prefs?.hidden) {
2814+
return undefined;
2815+
}
27992816

2800-
const typedBalance = balance;
2801-
const priceRaw = this.state.assetsPrice[typedAssetId];
2802-
const price: AssetPrice = priceRaw ?? {
2803-
price: 0,
2804-
lastUpdated: 0,
2805-
};
2817+
const assetChainId = extractChainId(assetId);
28062818

2807-
// Compute fiat value using BigNumber for precision
2808-
// Note: typedBalance.amount is already in human-readable format (e.g., "1" for 1 ETH)
2809-
// so we do NOT divide by 10^decimals here
2810-
const balanceAmount = new BigNumberJS(typedBalance.amount || '0');
2811-
const fiatValue = balanceAmount
2812-
.multipliedBy(price.price || 0)
2813-
.toNumber();
2814-
2815-
const asset: Asset = {
2816-
id: typedAssetId,
2817-
chainId: assetChainId,
2818-
balance: typedBalance,
2819-
metadata,
2820-
price,
2821-
fiatValue,
2822-
};
2819+
// Skip native tokens on Tempo networks
2820+
if (this.#shouldHideNativeToken(assetChainId, metadata)) {
2821+
return undefined;
2822+
}
2823+
2824+
if (filters?.chainIdSet && !filters.chainIdSet.has(assetChainId)) {
2825+
return undefined;
2826+
}
28232827

2824-
result[account.id][typedAssetId] = asset;
2828+
// Filter by asset type
2829+
if (filters?.assetTypeSet) {
2830+
const tokenAssetType = this.#tokenStandardToAssetType(metadata.type);
2831+
if (!filters.assetTypeSet.has(tokenAssetType)) {
2832+
return undefined;
28252833
}
28262834
}
28272835

2828-
return result;
2836+
const priceRaw = this.state.assetsPrice[assetId];
2837+
const price: AssetPrice = priceRaw ?? {
2838+
price: 0,
2839+
lastUpdated: 0,
2840+
};
2841+
2842+
// Compute fiat value using BigNumber for precision
2843+
// Note: balance.amount is already in human-readable format (e.g., "1" for 1 ETH)
2844+
// so we do NOT divide by 10^decimals here
2845+
const balanceAmount = new BigNumberJS(balance.amount || '0');
2846+
const fiatValue = balanceAmount.multipliedBy(price.price || 0).toNumber();
2847+
2848+
return {
2849+
id: assetId,
2850+
chainId: assetChainId,
2851+
balance,
2852+
metadata,
2853+
price,
2854+
fiatValue,
2855+
};
28292856
}
28302857

28312858
/**

0 commit comments

Comments
 (0)