UNPKG

@ledgerhq/live-common

Version:
102 lines (91 loc) 3.33 kB
import BigNumber from "bignumber.js"; import { emptyHistoryCache, encodeTokenAccountId } from "@ledgerhq/coin-framework/account/index"; import type { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; import type { Operation, SyncConfig, TokenAccount } from "@ledgerhq/types-live"; import { encodeOperationId } from "@ledgerhq/coin-framework/operation"; import { listTokensForCryptoCurrency } from "@ledgerhq/cryptoassets"; import { AssetInfo, Balance } from "@ledgerhq/coin-framework/api/types"; export interface OperationCommon extends Operation { extra: Record<string, any>; } export const getAssetIdFromTokenId = (tokenId: string): string => tokenId.split("/")[2]; function buildTokenAccount({ parentAccountId, assetBalance, token, operations, }: { parentAccountId: string; assetBalance: Balance; token: TokenCurrency; operations: OperationCommon[]; }): TokenAccount { const id = encodeTokenAccountId(parentAccountId, token); const balance = new BigNumber(assetBalance.value.toString() || "0"); // TODO: recheck this logic const spendableBalance = new BigNumber(assetBalance.value.toString()).minus( new BigNumber(assetBalance.locked?.toString() || "0"), ); const tokenOperations = operations.map(op => ({ ...op, id: encodeOperationId(id, op.hash, op.extra?.ledgerOpType), accountId: id, type: op.extra?.ledgerOpType, value: op.extra?.assetAmount ? new BigNumber(op.extra?.assetAmount) : op.value, })); return { type: "TokenAccount", id, parentId: parentAccountId, token, operationsCount: operations.length, operations: tokenOperations, pendingOperations: [], balance, spendableBalance: spendableBalance, swapHistory: [], creationDate: operations.length > 0 ? operations[operations.length - 1].date : new Date(), balanceHistoryCache: emptyHistoryCache, // calculated in the jsHelpers }; } export async function buildSubAccounts({ currency, accountId, allTokenAssetsBalances, syncConfig, operations, getTokenFromAsset, }: { currency: CryptoCurrency; accountId: string; allTokenAssetsBalances: Balance[]; syncConfig: SyncConfig; operations: OperationCommon[]; getTokenFromAsset?: (asset: AssetInfo) => Promise<TokenCurrency | undefined>; }): Promise<TokenAccount[]> { const { blacklistedTokenIds = [] } = syncConfig; const allTokens = listTokensForCryptoCurrency(currency); const tokenAccounts: TokenAccount[] = []; if (allTokens.length === 0 || allTokenAssetsBalances.length === 0) { return tokenAccounts; } for (const balance of allTokenAssetsBalances) { const token = getTokenFromAsset && (await getTokenFromAsset(balance.asset)); // NOTE: for future tokens, will need to check over currencyName/standard(erc20,trc10,trc20, etc)/id if (token && !blacklistedTokenIds.includes(token.id)) { tokenAccounts.push( buildTokenAccount({ parentAccountId: accountId, assetBalance: balance, token, operations: operations.filter( op => op.extra.assetReference === balance.asset?.["assetReference"] && op.extra.assetOwner === balance.asset?.["assetOwner"], // NOTE: we could narrow type ), }), ); } } return tokenAccounts; }