UNPKG

@ledgerhq/coin-filecoin

Version:
166 lines 5.97 kB
import { log } from "@ledgerhq/logs"; import { parseCurrencyUnit } from "@ledgerhq/coin-framework/currencies"; import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets"; import { BigNumber } from "bignumber.js"; import { TxStatus } from "../types"; import { fetchBalances, fetchBlockHeight, fetchTxs } from "../api/api"; import { encodeAccountId } from "@ledgerhq/coin-framework/account"; import { encodeOperationId } from "@ledgerhq/coin-framework/operation"; import flatMap from "lodash/flatMap"; import { buildTokenAccounts } from "../erc20/tokenAccounts"; export const getUnit = () => getCryptoCurrencyById("filecoin").units[0]; export const processTxs = (txs) => { // Group all tx types related to same tx cid into the same object const txsByTxCid = txs.reduce((txsByTxCidResult, currentTx) => { const { hash: txCid, type: txType } = currentTx; const txByType = txsByTxCidResult[txCid] || {}; switch (txType) { case "Send": txByType.Send = currentTx; break; case "InvokeContract": txByType.InvokeContract = currentTx; break; case "Fee": txByType.Fee = currentTx; break; default: log("warn", `tx type [${txType}] on tx cid [${txCid}] was not recognized.`); break; } txsByTxCidResult[txCid] = txByType; return txsByTxCidResult; }, {}); // Once all tx types have been grouped, we want to find const processedTxs = []; for (const txCid in txsByTxCid) { const item = txsByTxCid[txCid]; const feeTx = item.Fee; let mainTx; if ("Send" in item) { mainTx = item.Send; } else if ("InvokeContract" in item) { mainTx = item.InvokeContract; } else { log("warn", `unexpected tx type, tx with cid [${txCid}] and payload [${JSON.stringify(item)}]`); } if (!mainTx) { if (feeTx) { log("warn", `feeTx [${feeTx.hash}] found without a mainTx linked to it.`); } continue; } if (feeTx) { mainTx.fee = feeTx.amount; } processedTxs.push(mainTx); } return processedTxs; }; export const mapTxToOps = (accountId, { address }) => (tx) => { const { to, from, hash, timestamp, amount, fee, status } = tx; const ops = []; const date = new Date(timestamp * 1000); const value = parseCurrencyUnit(getUnit(), amount.toString()); const feeToUse = parseCurrencyUnit(getUnit(), (fee || 0).toString()); const isSending = address === from; const isReceiving = address === to; const hasFailed = status !== TxStatus.Ok; if (isSending) { const type = value.eq(0) ? "FEES" : "OUT"; ops.push({ id: encodeOperationId(accountId, hash, type), hash, type, value: value.plus(feeToUse), fee: feeToUse, blockHeight: tx.height, blockHash: null, accountId, senders: [from], recipients: [to], date, extra: {}, hasFailed, }); } if (isReceiving) { const type = value.eq(0) ? "FEES" : "IN"; ops.push({ id: encodeOperationId(accountId, hash, type), hash, type, value, fee: feeToUse, blockHeight: tx.height, blockHash: null, accountId, senders: [from], recipients: [to], date, extra: {}, hasFailed, }); } return ops; }; export const getAddress = (a) => ({ address: a.freshAddress, derivationPath: a.freshAddressPath }); export const getTxToBroadcast = (operation, signature, rawData) => { const { sender, recipient, gasLimit, gasFeeCap, gasPremium, method, version, nonce, signatureType, params, value, } = rawData; return { message: { version, method, nonce, params: params ?? "", to: recipient, from: sender, gaslimit: gasLimit.toNumber(), gaspremium: gasPremium.toString(), gasfeecap: gasFeeCap.toString(), value, }, signature: { type: signatureType, data: signature, }, }; }; export const getAccountShape = async (info) => { const { address, currency, derivationMode } = info; const accountId = encodeAccountId({ type: "js", version: "2", currencyId: currency.id, xpubOrAddress: address, derivationMode, }); const blockHeight = await fetchBlockHeight(); const balance = await fetchBalances(address); const rawTxs = await fetchTxs(address); const tokenAccounts = await buildTokenAccounts(address, accountId, info.initialAccount); const result = { id: accountId, subAccounts: tokenAccounts, balance: new BigNumber(balance.total_balance), spendableBalance: new BigNumber(balance.spendable_balance), operations: flatMap(processTxs(rawTxs), mapTxToOps(accountId, info)).sort((a, b) => b.date.getTime() - a.date.getTime()), blockHeight: blockHeight.current_block_identifier.index, }; return result; }; export const getSubAccount = (account, tx) => { const subAccount = tx.subAccountId && account.subAccounts ? account.subAccounts.find(sa => sa.id === tx.subAccountId) : null; return subAccount; }; /** * convert a value in a given unit to a normalized value * For instance, for 1 BTC, valueFromUnit(1, btcUnit) returns 100000000 * @memberof countervalue */ export const valueFromUnit = (valueInUnit, unit) => valueInUnit.times(new BigNumber(10).pow(unit.magnitude)); //# sourceMappingURL=utils.js.map