@ledgerhq/coin-hedera
Version:
Ledger Hedera Coin integration
213 lines • 7.99 kB
JavaScript
"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