@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
84 lines (78 loc) • 3.16 kB
text/typescript
import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
import { MappedAsset, CurrenciesByProviderId, GroupedCurrencies } from "./type";
import {
currenciesByMarketcap,
getCryptoCurrencyById,
findTokenById,
hasCryptoCurrencyId,
} from "../currencies";
import { getMappedAssets } from "./api";
export const loadCurrenciesByProvider = async (
coinsAndTokensSupported: CryptoOrTokenCurrency[],
): Promise<GroupedCurrencies> => {
const [sortedCurrenciesSupported, assets] = await Promise.all([
currenciesByMarketcap(coinsAndTokensSupported),
getMappedAssets(),
]);
return groupCurrenciesByProvider(assets, sortedCurrenciesSupported);
};
export const groupCurrenciesByProvider = (
assets: MappedAsset[],
sortedCurrencies: CryptoOrTokenCurrency[],
): GroupedCurrencies => {
const assetsByLedgerId: Map<string, MappedAsset> = new Map();
for (const asset of assets) {
/// FIXME(LIVE-10508) drop usage of toLowerCase
assetsByLedgerId.set(asset.ledgerId.toLowerCase(), asset);
}
const assetsByProviderId: Map<string, CurrenciesByProviderId> = new Map();
const sortedCryptoCurrencies: CryptoOrTokenCurrency[] = [];
// iterate over currencies by preserving their order
for (const ledgerCurrency of sortedCurrencies) {
/// FIXME(LIVE-10508) drop usage of toLowerCase
const asset = assetsByLedgerId.get(ledgerCurrency.id.toLowerCase());
if (asset) {
// we only yield the intersection of currencies and mapped assets
const existingEntry = assetsByProviderId.get(asset.providerId);
if (!existingEntry) {
assetsByProviderId.set(asset.providerId, {
providerId: asset.providerId,
currenciesByNetwork: [ledgerCurrency],
});
} else {
existingEntry.currenciesByNetwork.push(ledgerCurrency);
}
}
}
// in this case, the first currency of the provider is the one we want to display (Wasn't true)
// So we need to take the first crypto or token currency of each provider to fix that
for (const [, { currenciesByNetwork }] of assetsByProviderId.entries()) {
const firstCrypto = currenciesByNetwork.find(c => c.type === "CryptoCurrency");
const elem = firstCrypto ?? currenciesByNetwork.find(c => c.type === "TokenCurrency");
if (elem) {
sortedCryptoCurrencies.push(elem);
}
}
return {
currenciesByProvider: Array.from(assetsByProviderId.values()),
sortedCryptoCurrencies,
};
};
export const searchByProviderId = (list: MappedAsset[], providerId: string) =>
list.filter(elem => elem.providerId.toLowerCase() === providerId.toLowerCase());
export const searchByNameOrTicker = (list: MappedAsset[], nameOrTicker: string) =>
list.filter(
elem =>
elem.name.toLowerCase().includes(nameOrTicker.toLowerCase()) ||
elem.ticker.toLowerCase().includes(nameOrTicker.toLowerCase()),
);
export const getTokenOrCryptoCurrencyById = (id: string): CryptoOrTokenCurrency => {
if (hasCryptoCurrencyId(id)) {
return getCryptoCurrencyById(id);
}
const token = findTokenById(id);
if (!token) {
throw new Error(`token with id "${id}" not found`);
}
return token;
};