UNPKG

@ledgerhq/coin-internet_computer

Version:
130 lines 4.76 kB
import { decodeAccountId, encodeAccountId } from "@ledgerhq/coin-framework/account/index"; import { fetchBalance, fetchBlockHeight, fetchTxns } from "../../api"; import flatMap from "lodash/flatMap"; import BigNumber from "bignumber.js"; import { ICP_FEES } from "../../consts"; import { encodeOperationId } from "@ledgerhq/coin-framework/operation"; import { normalizeEpochTimestamp } from "../../common-logic/utils"; import invariant from "invariant"; import { deriveAddressFromPubkey, hashTransaction, } from "@zondax/ledger-live-icp"; export const getAccountShape = async (info) => { const { currency, derivationMode, rest = {}, initialAccount } = info; const publicKey = reconciliatePublicKey(rest.publicKey, initialAccount); invariant(publicKey, "publicKey is required"); // deriving address from public key const address = await deriveAddressFromPubkey(publicKey); invariant(address, "address is required"); const accountId = encodeAccountId({ type: "js", version: "2", currencyId: currency.id, xpubOrAddress: publicKey, derivationMode, }); // log("debug", `Generation account shape for ${address}`); const blockHeight = await fetchBlockHeight(); const balance = await fetchBalance(address); const txns = await fetchTxns(address, BigInt(blockHeight.toString()), initialAccount ? BigInt(initialAccount.blockHeight.toString()) : undefined); const result = { id: accountId, balance, spendableBalance: balance, operations: flatMap(txns, mapTxToOps(accountId, address)), blockHeight: blockHeight.toNumber(), operationsCount: (initialAccount?.operations.length ?? 0) + txns.length, xpub: publicKey, }; return result; }; function reconciliatePublicKey(publicKey, initialAccount) { if (publicKey) return publicKey; if (initialAccount) { const { xpubOrAddress } = decodeAccountId(initialAccount.id); return xpubOrAddress; } throw new Error("publicKey wasn't properly restored"); } const mapTxToOps = (accountId, address, fee = ICP_FEES) => { return (txInfo) => { const { transaction: txn } = txInfo; const ops = []; if (txn.operation === undefined) { return []; } if ("Transfer" in txn.operation === undefined) { return []; } const timeStamp = txn.timestamp[0]?.timestamp_nanos ?? Date.now(); let amount = BigNumber(0); let fromAccount = ""; let toAccount = ""; let hash = ""; if ("Transfer" in txn.operation) { amount = BigNumber(txn.operation.Transfer.amount.e8s.toString()); fromAccount = txn.operation.Transfer.from; toAccount = txn.operation.Transfer.to; hash = hashTransaction({ from: fromAccount, to: toAccount, amount: txn.operation.Transfer.amount.e8s, fee: txn.operation.Transfer.fee.e8s, memo: txn.memo, created_at_time: txn.created_at_time[0]?.timestamp_nanos ?? BigInt(0), }); } const blockHeight = Number(txInfo.id); const blockHash = ""; const memo = txInfo.transaction.memo.toString(); const date = new Date(normalizeEpochTimestamp(timeStamp.toString())); const value = amount.abs(); const feeToUse = BigNumber(fee); const isSending = address === fromAccount; const isReceiving = address === toAccount; let type; if (isSending) { type = "OUT"; } else { type = "IN"; } if (isSending) { ops.push({ id: encodeOperationId(accountId, hash, type), hash, type, value: value.plus(feeToUse), fee: feeToUse, blockHeight, blockHash, accountId, senders: [fromAccount], recipients: [toAccount], date, extra: { memo, }, }); } if (isReceiving) { ops.push({ id: encodeOperationId(accountId, hash, type), hash, type, value, fee: feeToUse, blockHeight, blockHash, accountId, senders: [fromAccount], recipients: [toAccount], date, extra: { memo, }, }); } return ops; }; }; //# sourceMappingURL=account.js.map