UNPKG

@ledgerhq/coin-hedera

Version:
125 lines 6.17 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildIterateResult = exports.getAccountShape = void 0; const account_1 = require("@ledgerhq/ledger-wallet-framework/account"); const jsHelpers_1 = require("@ledgerhq/ledger-wallet-framework/bridge/jsHelpers"); const derivation_1 = require("@ledgerhq/ledger-wallet-framework/derivation"); const bignumber_js_1 = require("bignumber.js"); const invariant_1 = __importDefault(require("invariant")); const constants_1 = require("../constants"); const logic_1 = require("../logic"); const utils_1 = require("../logic/utils"); const api_1 = require("../network/api"); const utils_2 = require("../network/utils"); const utils_3 = require("./utils"); const getAccountShape = async (info, { blacklistedTokenIds }) => { const { currency, derivationMode, address, initialAccount } = info; const config = (0, utils_1.resolveConfig)(currency.id); (0, invariant_1.default)(address, "hedera: address is expected"); const evmAddress = await (0, utils_2.toEVMAddress)({ configOrCurrencyId: config, accountId: address }); (0, invariant_1.default)(evmAddress, `hedera: evm address is missing for ${address}`); const liveAccountId = (0, account_1.encodeAccountId)({ type: "js", version: "2", currencyId: currency.id, xpubOrAddress: address, derivationMode, }); // get current account balance and tokens // tokens are fetched with separate requests to get "created_timestamp" for each token // based on this, ASSOCIATE_TOKEN operations can be connected with tokens const [mirrorAccount, mirrorTokens, erc20Tokens] = await Promise.all([ api_1.apiClient.getAccount({ configOrCurrencyId: config, address }), api_1.apiClient.getAccountTokens({ configOrCurrencyId: config, address }), (0, utils_2.getERC20BalancesForAccountV2)({ configOrCurrencyId: config, address }), ]); const accountBalance = new bignumber_js_1.BigNumber(mirrorAccount.balance.balance); // we should sync again when new tokens are added or blacklist changes const syncHash = await (0, account_1.getSyncHash)(currency.id, blacklistedTokenIds); const shouldSyncFromScratch = !initialAccount || syncHash !== initialAccount?.syncHash; const pendingOperations = shouldSyncFromScratch ? [] : (initialAccount?.pendingOperations ?? []); const oldOperations = shouldSyncFromScratch ? [] : (initialAccount?.operations ?? []); const latestOperation = oldOperations[0]; // grab latest operation timestamps for incremental sync let latestOperationTimestamp = null; if (!shouldSyncFromScratch && latestOperation) { const timestamp = Math.floor(latestOperation.date.getTime() / 1000); latestOperationTimestamp = new bignumber_js_1.BigNumber(timestamp).toFixed(9); } const latestAccountOperations = await (0, logic_1.listOperationsV2)({ currencyId: currency.id, address, evmAddress, mirrorTokens, erc20Tokens, ...(latestOperationTimestamp && { cursor: latestOperationTimestamp }), fetchAllPages: true, skipFeesForTokenOperations: false, useEncodedHash: true, useSyntheticBlocks: false, }); const newOperations = await (0, utils_3.prepareOperations)(latestAccountOperations.coinOperations, latestAccountOperations.tokenOperations); const enrichedNewOperations = (0, utils_3.applyPendingExtras)(newOperations, pendingOperations); const operations = shouldSyncFromScratch ? enrichedNewOperations : (0, jsHelpers_1.mergeOps)(oldOperations, enrichedNewOperations); const delegation = typeof mirrorAccount.staked_node_id === "number" ? { nodeId: mirrorAccount.staked_node_id, delegated: accountBalance, pendingReward: new bignumber_js_1.BigNumber(mirrorAccount.pending_reward), } : null; const newSubAccounts = await (0, utils_3.getSubAccounts)({ ledgerAccountId: liveAccountId, latestTokenOperations: latestAccountOperations.tokenOperations, mirrorTokens, erc20Tokens, }); const subAccounts = shouldSyncFromScratch ? newSubAccounts : (0, utils_3.mergeSubAccounts)(initialAccount, newSubAccounts); return { id: liveAccountId, freshAddress: address, syncHash, lastSyncDate: new Date(), balance: accountBalance, spendableBalance: accountBalance, operations: operations, operationsCount: operations.length, // NOTE: there are no "blocks" in hedera // set a value just so that operations are considered confirmed according to isConfirmedOperation blockHeight: constants_1.HARDCODED_BLOCK_HEIGHT, subAccounts, hederaResources: { maxAutomaticTokenAssociations: mirrorAccount.max_automatic_token_associations, isAutoTokenAssociationEnabled: mirrorAccount.max_automatic_token_associations === -1, delegation, }, }; }; exports.getAccountShape = getAccountShape; const buildIterateResult = async ({ result: rootResult }) => { return async ({ currency, derivationMode, index }) => { const mirrorAccounts = await api_1.apiClient.getAccountsForPublicKey({ configOrCurrencyId: currency.id, publicKey: rootResult.publicKey, }); const addresses = mirrorAccounts.map(a => a.account); const derivationScheme = (0, derivation_1.getDerivationScheme)({ derivationMode, currency }); const freshAddressPath = (0, derivation_1.runDerivationScheme)(derivationScheme, currency, { account: index }); return addresses[index] ? { address: addresses[index], publicKey: addresses[index], path: freshAddressPath, } : null; }; }; exports.buildIterateResult = buildIterateResult; //# sourceMappingURL=synchronisation.js.map