UNPKG

@ledgerhq/coin-hedera

Version:
213 lines 7.99 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.hgraphClient = void 0; const live_env_1 = require("@ledgerhq/live-env"); const live_network_1 = __importDefault(require("@ledgerhq/live-network")); const bignumber_js_1 = __importDefault(require("bignumber.js")); const invariant_1 = __importDefault(require("invariant")); const getPaginationDirection = (fetchAllPages, order) => { if (fetchAllPages) return "_gt"; return order === "asc" ? "_gt" : "_lt"; }; const throwOnGraphQLErrors = (res, context) => { if ("errors" in res.data) { const reason = res.data.errors[0]?.message ?? ""; throw new Error(`hedera: failed to fetch ${context} from Hgraph: ${reason}`); } }; async function getLatestIndexedConsensusTimestamp() { const res = await (0, live_network_1.default)({ url: (0, live_env_1.getEnv)("API_HEDERA_HGRAPH"), method: "POST", data: { query: ` query LatestTransaction { ethereum_transaction( limit: 1, order_by: { consensus_timestamp: desc } ) { consensus_timestamp } } `, }, }); throwOnGraphQLErrors(res, "latest indexed consensus timestamp"); const lastTransactionTimestamp = res.data.data.ethereum_transaction[0]?.consensus_timestamp; (0, invariant_1.default)(lastTransactionTimestamp, "No transactions found in Hgraph"); return new bignumber_js_1.default(lastTransactionTimestamp); } async function getERC20Balances({ address }) { const res = await (0, live_network_1.default)({ url: (0, live_env_1.getEnv)("API_HEDERA_HGRAPH"), method: "POST", data: { query: ` query GetAccountPortfolio($accountId: bigint!) { erc_token_account( where: { account_id: { _eq: $accountId } } ) { token_id balance balance_timestamp created_timestamp } } `, variables: { accountId: address.split(".").pop(), }, }, }); throwOnGraphQLErrors(res, "ERC20 balances"); return res.data.data.erc_token_account; } async function getERC20Transfers({ address, tokenEvmAddresses, timestamp, limit = 100, order = "desc", fetchAllPages, }) { if (tokenEvmAddresses.length === 0) { return []; } let hasMorePages = true; let cursor = timestamp?.replace(".", "") ?? null; const transfers = []; const accountId = address.split(".").pop(); while (hasMorePages) { const res = await (0, live_network_1.default)({ url: (0, live_env_1.getEnv)("API_HEDERA_HGRAPH"), method: "POST", data: { query: ` query GetAccountTransfers($accountId: bigint!, $tokenEvmAddresses: [String!]!, $cursor: bigint, $limit: Int!) { erc_token_transfer( where: { transfer_type: { _in: ["transfer", "mint", "burn"] } contract_type: { _eq: "ERC_20" } token_evm_address: { _in: $tokenEvmAddresses } ${cursor ? `consensus_timestamp: { ${getPaginationDirection(fetchAllPages, order)}: $cursor }` : ""} _or: [ { sender_account_id: { _eq: $accountId } } { receiver_account_id: { _eq: $accountId } } ] } order_by: { consensus_timestamp: ${order} } limit: $limit ) { token_id token_evm_address sender_evm_address sender_account_id receiver_evm_address receiver_account_id payer_account_id amount transfer_type consensus_timestamp transaction_hash } } `, variables: { accountId, tokenEvmAddresses, limit, ...(cursor && { cursor }), }, }, }); throwOnGraphQLErrors(res, "ERC20 transfers"); const newTransfers = res.data.data.erc_token_transfer; transfers.push(...newTransfers); // stop fetching if pagination mode is used and we reached the limit if (!fetchAllPages && transfers.length >= limit) { hasMorePages = false; } // stop if no more results (empty array indicates no more data) if (newTransfers.length === 0 || newTransfers.length < limit) { hasMorePages = false; } if (hasMorePages) { // update cursor to the last item's timestamp for next iteration const lastTransfer = newTransfers[newTransfers.length - 1]; cursor = lastTransfer.consensus_timestamp.toString(); } } // ensure we don't exceed the limit when not fetching all pages if (!fetchAllPages && transfers.length > limit) { transfers.splice(limit); } return transfers; } async function getERC20TransfersByTimestampRange({ startTimestamp, endTimestamp, order = "desc", limit = 100, }) { const transfers = []; let hasMorePages = true; let cursor = null; const normalizedStartTimestamp = startTimestamp.replace(".", ""); const normalizedEndTimestamp = endTimestamp.replace(".", ""); while (hasMorePages) { const res = await (0, live_network_1.default)({ url: (0, live_env_1.getEnv)("API_HEDERA_HGRAPH"), method: "POST", data: { query: ` query GetAccountTransfers($startTimestamp: bigint!, $endTimestamp: bigint!, $cursor: bigint, $limit: Int!) { erc_token_transfer( where: { transfer_type: { _in: ["transfer", "mint", "burn"] } contract_type: { _eq: "ERC_20" } consensus_timestamp: { ${cursor ? "_gt: $cursor" : "_gte: $startTimestamp"} _lt: $endTimestamp } } order_by: { consensus_timestamp: ${order} } limit: $limit ) { token_id token_evm_address sender_evm_address sender_account_id receiver_evm_address receiver_account_id payer_account_id amount transfer_type consensus_timestamp transaction_hash } } `, variables: { startTimestamp: normalizedStartTimestamp, endTimestamp: normalizedEndTimestamp, limit, ...(cursor && { cursor }), }, }, }); throwOnGraphQLErrors(res, "ERC20 transfers by timestamp range"); const newTransfers = res.data.data.erc_token_transfer; transfers.push(...newTransfers); // stop if no more results if (newTransfers.length === 0 || newTransfers.length < limit) { hasMorePages = false; } if (hasMorePages) { // update cursor to the last item's timestamp for next iteration const lastTransfer = newTransfers[newTransfers.length - 1]; cursor = lastTransfer.consensus_timestamp.toString(); } } return transfers; } exports.hgraphClient = { getLatestIndexedConsensusTimestamp, getERC20Balances, getERC20Transfers, getERC20TransfersByTimestampRange, }; //# sourceMappingURL=hgraph.js.map