@ledgerhq/coin-hedera
Version:
Ledger Hedera Coin integration
75 lines • 3.62 kB
JavaScript
import { getCryptoAssetsStore } from "@ledgerhq/cryptoassets/state";
import { LedgerAPI4xx } from "@ledgerhq/errors";
import { promiseAllBatched } from "@ledgerhq/live-promise";
import BigNumber from "bignumber.js";
import hederaCoinConfig from "../config";
import { HederaAddAccountError } from "../errors";
import { apiClient } from "../network/api";
import { getERC20BalancesForAccountV2 } from "../network/utils";
export async function getBalance(currency, address) {
try {
const coinConfig = hederaCoinConfig.getCoinConfig(currency.id);
// Fetch only the specific staked node (or nothing at all for non-staking
// accounts) instead of paginating the full /network/nodes list. The
// validator lookup is chained on the account promise so it still runs
// concurrently with the token fetches.
const mirrorAccountPromise = apiClient.getAccount(address);
const validatorPromise = mirrorAccountPromise.then(account => typeof account.staked_node_id === "number" && account.staked_node_id >= 0
? apiClient.getNode(account.staked_node_id)
: null);
const [mirrorAccount, mirrorTokens, erc20TokenBalances, validator] = await Promise.all([
mirrorAccountPromise,
apiClient.getAccountTokens(address),
coinConfig.useHgraphForErc20 ? getERC20BalancesForAccountV2(address) : Promise.resolve([]),
validatorPromise,
]);
const mixedTokens = [...mirrorTokens, ...erc20TokenBalances];
const nativeBalance = {
asset: { type: "native" },
value: BigInt(mirrorAccount.balance.balance),
...(validator && {
stake: {
uid: address,
address,
asset: { type: "native" },
state: "active",
amount: BigInt(mirrorAccount.balance.balance) + BigInt(mirrorAccount.pending_reward),
amountDeposited: BigInt(mirrorAccount.balance.balance),
amountRewarded: BigInt(mirrorAccount.pending_reward),
delegate: validator.node_account_id,
details: {
overstaked: BigInt(validator.stake) >= BigInt(validator.max_stake),
},
},
}),
};
const tokenBalances = await promiseAllBatched(3, mixedTokens, async (item) => {
const tokenAddress = "token_id" in item ? item.token_id : item.token.contractAddress;
const calToken = await getCryptoAssetsStore().findTokenByAddressInCurrency(tokenAddress, currency.id);
if (!calToken || !calToken.units.length) {
return null;
}
const roundedValue = new BigNumber(item.balance).toFixed(0);
return {
value: BigInt(roundedValue),
asset: {
type: calToken.tokenType,
assetReference: calToken.contractAddress,
assetOwner: address,
name: calToken.name,
unit: calToken.units[0],
},
};
});
const balances = [nativeBalance, ...tokenBalances].filter((balance) => balance !== null);
return balances;
}
catch (err) {
const isNonExistentAccount = err instanceof HederaAddAccountError || (err instanceof LedgerAPI4xx && err.status === 404);
if (isNonExistentAccount) {
return [];
}
throw err;
}
}
//# sourceMappingURL=getBalance.js.map