@ledgerhq/coin-icon
Version:
Ledger Icon Coin integration
112 lines • 3.75 kB
JavaScript
import network from "@ledgerhq/live-network/network";
import { BigNumber } from "bignumber.js";
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
import { LIMIT } from "../constants";
import { isTestnet } from "../logic";
import { log } from "@ledgerhq/logs";
import querystring from "querystring";
import { getCoinConfig } from "../config";
/**
* Returns Testnet API URL if the current network is testnet
*
* @param {network} network
*/
function getApiUrl(network) {
const currencyConfig = getCoinConfig();
let apiUrl = currencyConfig.infra.indexer;
if (isTestnet(network)) {
apiUrl = currencyConfig.infra.indexer_testnet;
}
return apiUrl;
}
async function fetch(url) {
const { data } = await network({
method: "GET",
url,
});
if (data.Error) {
log("icon-error", data.Error, {
url,
});
throw new Error(data.Error);
}
return data;
}
export const getAccount = async (addr, network) => {
const data = await fetch(`${getApiUrl(network)}/addresses/details/${addr}`);
return data;
};
export const getCurrentBlockHeight = async (network) => {
const data = await fetch(`${getApiUrl(network)}/blocks`);
return data?.[0].number;
};
/**
* Returns true if account is the signer
*/
function isSender(transaction, addr) {
return transaction.from_address === addr;
}
/**
* Map transaction to an Operation Type
*/
function getOperationType(transaction, addr) {
return isSender(transaction, addr) ? "OUT" : "IN";
}
/**
* Map transaction to a correct Operation Value (affecting account balance)
*/
function getOperationValue(transaction, addr) {
if (isSender(transaction, addr)) {
return transaction.value
? new BigNumber(transaction.value).plus(transaction.transaction_fee)
: new BigNumber(0);
}
else {
return transaction.value ? new BigNumber(transaction.value) : new BigNumber(0);
}
}
/**
* Map the ICON history transaction to a Ledger Live Operation
*/
function txToOperation(accountId, addr, transaction) {
const type = getOperationType(transaction, addr);
return {
id: encodeOperationId(accountId, transaction.hash, type),
accountId,
fee: new BigNumber(transaction.transaction_fee),
value: getOperationValue(transaction, addr),
type,
hash: transaction.hash,
blockHash: null,
blockHeight: transaction.block_number,
date: new Date(transaction.block_timestamp / 1000),
senders: [transaction.from_address],
recipients: [transaction.to_address],
extra: {},
hasFailed: transaction.status !== "0x1",
};
}
/**
* Fetch operation list
*/
export const getOperations = async (accountId, addr, skip, network, maxLength) => {
return await fetchOperationList(accountId, addr, skip, network, maxLength);
};
export const fetchOperationList = async (accountId, addr, skip, network, maxLength, prevOperations = []) => {
const data = await getTxHistory(addr, skip, network);
const operations = data.map((transaction) => txToOperation(accountId, addr, transaction));
const mergedOp = [...prevOperations, ...operations];
if (operations.length < LIMIT || operations.length >= maxLength) {
return mergedOp;
}
return await fetchOperationList(accountId, addr, skip + LIMIT, network, maxLength, mergedOp);
};
export const getTxHistory = async (addr, skip, network, limit = LIMIT) => {
const query = querystring.stringify({
skip: skip,
limit: limit,
});
const data = await fetch(`${getApiUrl(network)}/transactions/address/${addr}?${query}`);
return data;
};
//# sourceMappingURL=index.js.map