@covalenthq/client-sdk
Version:
<div align="center"> <a href="https://goldrush.dev/products/goldrush/" target="_blank" rel="noopener noreferrer"> <img alt="GoldRush TS SDK Logo" src="./repo-static/ts-sdk-banner.png" style="max-width: 100%;"/> </a> </div>
1,111 lines (1,105 loc) • 170 kB
JavaScript
var version = "2.2.4";
const bigIntParser = (val) => {
if (val === null || val === undefined) {
return null;
}
return BigInt(val);
};
const baseUrl = "https://api.covalenthq.com/v1";
const endpointGenerator = (extension = "", params = []) => {
extension = extension.replace(baseUrl, "");
if (extension.startsWith("/")) {
extension = extension.slice(1);
}
if (!extension.endsWith("/")) {
extension = `${extension}/`;
}
const urlParams = new URLSearchParams();
params.forEach((param) => {
if (param.value !== undefined && param.value !== null) {
urlParams.append(param.key, param.value.toString());
}
});
return new URL(`${baseUrl}/${extension}?${urlParams}`);
};
/**
* Cross Chain API
*
*/
class AllChainsService {
constructor(execution) {
this.execution = execution;
}
/**
*
* Commonly used to locate chains which an address is active on with a single API call.
*
* @param {string} walletAddress - The requested wallet address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetAddressActivityQueryParamOpts} queryParamOpts
* - `testnets`: Set to true to include testnets with activity in the response. By default, it's set to `false` and only returns mainnet activity.
*
*/
async getAddressActivity(walletAddress, queryParamOpts) {
const endpoint = endpointGenerator(`address/${walletAddress}/activity`, [
{
key: "testnets",
value: queryParamOpts?.testnets,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((activityItem) => ({
...activityItem,
last_seen_at: activityItem.last_seen_at
? new Date(activityItem.last_seen_at)
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to get transactions cross chains and addresses.
*
* @param {Chain[]} chains - An array of the chain names or IDs to retrieve transactions from. Defaults to all foundational chains.
* @param {string[]} addresses - An array of addresses for which transactions are fetched. Does not support name resolution.
* @param {number} limit - Number of transactions to return per page, up to the default max of 100 items.
* @param {string} before - Pagination cursor pointing to fetch transactions before a certain point.
* @param {string} after - Pagination cursor pointing to fetch transactions after a certain point.
* @param {boolean} withLogs - Whether to include raw logs in the response.
* @param {boolean} withDecodedLogs - Whether to include decoded logs in the response.
* @param {Quote | CryptocurrencyQuote} quoteCurrency - The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, `GBP`, `BTC` and `ETH`.
*
*/
async getMultiChainMultiAddressTransactions(queryParamOpts) {
const endpoint = endpointGenerator(`allchains/transactions`, [
{
key: "chains",
value: queryParamOpts?.chains,
},
{
key: "addresses",
value: queryParamOpts?.addresses,
},
{
key: "limit",
value: queryParamOpts?.limit,
},
{
key: "before",
value: queryParamOpts?.before,
},
{
key: "after",
value: queryParamOpts?.after,
},
{
key: "with-logs",
value: queryParamOpts?.withLogs,
},
{
key: "with-decoded-logs",
value: queryParamOpts?.withDecodedLogs,
},
{
key: "quote-currency",
value: queryParamOpts?.quoteCurrency,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((txItem) => ({
...txItem,
value: bigIntParser(txItem.value),
fees_paid: bigIntParser(txItem.fees_paid),
block_signed_at: txItem.block_signed_at
? new Date(txItem.block_signed_at)
: null,
log_events: txItem.log_events
? txItem.log_events.map((logItem) => ({
...logItem,
block_signed_at: logItem.block_signed_at
? new Date(logItem.block_signed_at)
: null,
}))
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
* @deprecated This method is deprecated and will be removed in the upcoming versions. Please use `AllChainsService.getMultiChainMultiAddressTransactions` instead.
*
* Commonly used to get transactions cross chains and addresses.
*
* @param {Chain[]} chains - An array of the chain names or IDs to retrieve transactions from. Defaults to all foundational chains.
* @param {string[]} addresses - An array of addresses for which transactions are fetched. Does not support name resolution.
* @param {number} limit - Number of transactions to return per page, up to the default max of 100 items.
* @param {string} before - Pagination cursor pointing to fetch transactions before a certain point.
* @param {string} after - Pagination cursor pointing to fetch transactions after a certain point.
* @param {boolean} withLogs - Whether to include raw logs in the response.
* @param {boolean} withDecodedLogs - Whether to include decoded logs in the response.
* @param {Quote | CryptocurrencyQuote} quoteCurrency - The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, `GBP`, `BTC` and `ETH`.
*
*/
async getMultiChainAndMultiAddressTransactions(queryParamOpts) {
return await this.getMultiChainMultiAddressTransactions(queryParamOpts);
}
/**
*
* @param {string} walletAddress - The requested wallet Address.
* @param {GetMultiChainBalanceQueryParamOpts} queryParamOpts
* - `quoteCurrency`: The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, `GBP`, `BTC`, and `ETH`.
* - `chains`: Array chain ids or chain names to query. Limited to 10 chains.
* - `limit`: The number of items to return. Default is 100.
* - `timestamp`: The timestamp to query balances at. If omitted, the latest balances are returned.
* - `cursorBefore`: The cursor of previous page.
*/
async getMultiChainBalances(walletAddress, queryParamOpts) {
const endpoint = endpointGenerator(`allchains/address/${walletAddress}/balances`, [
{
key: "chains",
value: queryParamOpts?.chains,
},
{
key: "quote-currency",
value: queryParamOpts?.quoteCurrency,
},
{
key: "limit",
value: queryParamOpts?.limit,
},
{
key: "cutoff-timestamp",
value: queryParamOpts?.cutoffTimestamp,
},
{
key: "before",
value: queryParamOpts?.before,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((balanceItem) => ({
...balanceItem,
balance: bigIntParser(balanceItem.balance),
balance_24h: bigIntParser(balanceItem.balance_24h),
last_transferred_at: balanceItem.last_transferred_at
? new Date(balanceItem.last_transferred_at)
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
}
async function* paginateEndpoint(endpoint, execution, parseData, implementation) {
let _endpoint = new URL(endpoint);
let hasMore = true;
let page_number = +(_endpoint.searchParams.get("page-number") ?? 0);
while (hasMore) {
try {
if (implementation === "pagination") {
_endpoint.searchParams.set("page-number", page_number.toString());
const parsedData = await execution.execute(_endpoint, parseData);
if (parsedData.error) {
throw parsedData;
}
if (!parsedData.data?.pagination?.has_more) {
hasMore = false;
}
else {
page_number++;
}
yield parsedData;
}
else if (implementation === "links") {
const parsedData = await execution.execute(_endpoint, parseData);
const prevLink = parsedData.data?.links?.prev || null;
if (!prevLink) {
hasMore = false;
}
else {
_endpoint = new URL(`${prevLink}?${_endpoint.searchParams}`);
}
yield parsedData;
}
}
catch (error) {
hasMore = false;
yield {
data: null,
error: true,
error_code: error?.cause?.code || error?.error_code || 500,
error_message: error?.cause?.message ||
error?.error_message ||
"Internal server error",
};
}
}
}
/**
* Balances APIs
*
*/
class BalanceService {
constructor(execution) {
this.execution = execution;
}
/**
*
* Commonly used to fetch the native, fungible (ERC20), and non-fungible (ERC721 & ERC1155) tokens held by an address. Response includes spot prices and other metadata.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} walletAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetTokenBalancesForWalletAddressQueryParamOpts} queryParamOpts
* - `quoteCurrency`: The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, and `GBP`.
* - `nft`: If `true`, NFTs will be included in the response.
* - `noNftFetch`: If `true`, only NFTs that have been cached will be included in the response. Helpful for faster response times.
* - `noSpam`: If `true`, the suspected spam tokens are removed. Supports `eth-mainnet` and `matic-mainnet`.
* - `noNftAssetMetadata`: If `true`, the response shape is limited to a list of collections and token ids, omitting metadata and asset information. Helpful for faster response times and wallets holding a large number of NFTs.
*
*/
async getTokenBalancesForWalletAddress(chainName, walletAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/address/${walletAddress}/balances_v2`, [
{
key: "quote-currency",
value: queryParamOpts?.quoteCurrency,
},
{
key: "nft",
value: queryParamOpts?.nft,
},
{
key: "no-nft-fetch",
value: queryParamOpts?.noNftFetch,
},
{
key: "no-spam",
value: queryParamOpts?.noSpam,
},
{
key: "no-nft-asset-metadata",
value: queryParamOpts?.noNftAssetMetadata,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((balanceItem) => ({
...balanceItem,
balance: bigIntParser(balanceItem.balance),
balance_24h: bigIntParser(balanceItem.balance_24h),
last_transferred_at: balanceItem.last_transferred_at
? new Date(balanceItem.last_transferred_at)
: null,
nft_data: balanceItem.nft_data
? balanceItem.nft_data.map((nftItem) => ({
...nftItem,
token_id: bigIntParser(nftItem.token_id),
token_balance: bigIntParser(nftItem.token_balance),
token_price_wei: bigIntParser(nftItem.token_price_wei),
}))
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to render a daily portfolio balance for an address broken down by the token. The timeframe is user-configurable, defaults to 30 days.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} walletAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetHistoricalPortfolioForWalletAddressQueryParamOpts} queryParamOpts
* - `quoteCurrency`: The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, and `GBP`.
* - `days`: The number of days to return data for. Defaults to 30 days.
*
*/
async getHistoricalPortfolioForWalletAddress(chainName, walletAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/address/${walletAddress}/portfolio_v2`, [
{
key: "quote-currency",
value: queryParamOpts?.quoteCurrency,
},
{
key: "days",
value: queryParamOpts?.days,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items =
data.data.items?.map((portfolioItem) => ({
...portfolioItem,
holdings: portfolioItem.holdings?.map((holdingItem) => ({
...holdingItem,
timestamp: holdingItem.timestamp
? new Date(holdingItem.timestamp)
: null,
close: {
...holdingItem.close,
balance: bigIntParser(holdingItem.close?.balance),
},
high: {
...holdingItem.high,
balance: bigIntParser(holdingItem.high?.balance),
},
low: {
...holdingItem.low,
balance: bigIntParser(holdingItem.low?.balance),
},
open: {
...holdingItem.open,
balance: bigIntParser(holdingItem.open?.balance),
},
})) || null,
})) || null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to render the transfer-in and transfer-out of a token along with historical prices from an address.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} walletAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetErc20TransfersForWalletAddressQueryParamOpts} queryParamOpts
* - `quoteCurrency`: The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, and `GBP`.
* - `contractAddress`: The requested contract address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* - `startingBlock`: The block height to start from, defaults to `0`.
* - `endingBlock`: The block height to end at, defaults to current block height.
* - `pageSize`: Number of items per page. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
*
*/
async *getErc20TransfersForWalletAddress(chainName, walletAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/address/${walletAddress}/transfers_v2`, [
{
key: "quote-currency",
value: queryParamOpts?.quoteCurrency,
},
{
key: "contract-address",
value: queryParamOpts?.contractAddress,
},
{
key: "starting-block",
value: queryParamOpts?.startingBlock,
},
{
key: "ending-block",
value: queryParamOpts?.endingBlock,
},
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((ercItem) => ({
...ercItem,
block_signed_at: ercItem.block_signed_at
? new Date(ercItem.block_signed_at)
: null,
value: bigIntParser(ercItem.value),
fees_paid: bigIntParser(ercItem.fees_paid),
transfers: ercItem.transfers
? ercItem.transfers.map((transferItem) => ({
...transferItem,
balance: bigIntParser(transferItem.balance),
block_signed_at: transferItem.block_signed_at
? new Date(transferItem.block_signed_at)
: null,
delta: bigIntParser(transferItem.delta),
}))
: null,
}))
: null;
}
return data;
};
for await (const data of paginateEndpoint(endpoint, this.execution, parseData, "pagination")) {
yield data;
}
}
/**
*
* Commonly used to render the transfer-in and transfer-out of a token along with historical prices from an address.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} walletAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetErc20TransfersForWalletAddressQueryParamOpts} queryParamOpts
* - `quoteCurrency`: The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, and `GBP`.
* - `contractAddress`: The requested contract address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* - `startingBlock`: The block height to start from, defaults to `0`.
* - `endingBlock`: The block height to end at, defaults to current block height.
* - `pageSize`: Number of items per page. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
*
*/
async getErc20TransfersForWalletAddressByPage(chainName, walletAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/address/${walletAddress}/transfers_v2`, [
{
key: "quote-currency",
value: queryParamOpts?.quoteCurrency,
},
{
key: "contract-address",
value: queryParamOpts?.contractAddress,
},
{
key: "starting-block",
value: queryParamOpts?.startingBlock,
},
{
key: "ending-block",
value: queryParamOpts?.endingBlock,
},
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((blockTxItem) => ({
...blockTxItem,
block_signed_at: blockTxItem.block_signed_at
? new Date(blockTxItem.block_signed_at)
: null,
fees_paid: bigIntParser(blockTxItem.fees_paid),
transfers: blockTxItem.transfers?.map((transferItem) => ({
...transferItem,
balance: bigIntParser(transferItem.balance),
block_signed_at: transferItem.block_signed_at
? new Date(transferItem.block_signed_at)
: null,
delta: bigIntParser(transferItem.delta),
})) || null,
value: bigIntParser(blockTxItem.value),
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to get a list of all the token holders for a specified ERC20 or ERC721 token. Returns historic token holders when block-height is set (defaults to `latest`). Useful for building pie charts of token holders.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} tokenAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetTokenHoldersV2ForTokenAddressQueryParamOpts} queryParamOpts
* - `blockHeight`: Ending block to define a block range. Omitting this parameter defaults to the latest block height.
* - `pageSize`: Number of items per page. Note: Currently, only values of `100` and `1000` are supported. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
* - `date`: Ending date to define a block range (YYYY-MM-DD). Omitting this parameter defaults to the current date.
*
*/
async *getTokenHoldersV2ForTokenAddress(chainName, tokenAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/tokens/${tokenAddress}/token_holders_v2`, [
{
key: "block-height",
value: queryParamOpts?.blockHeight,
},
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
{
key: "date",
value: queryParamOpts?.date,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((tokenItem) => ({
...tokenItem,
balance: bigIntParser(tokenItem.balance),
total_supply: bigIntParser(tokenItem.total_supply),
}))
: null;
}
return data;
};
for await (const data of paginateEndpoint(endpoint, this.execution, parseData, "pagination")) {
yield data;
}
}
/**
*
* Commonly used to get a list of all the token holders for a specified ERC20 or ERC721 token. Returns historic token holders when block-height is set (defaults to `latest`). Useful for building pie charts of token holders.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} tokenAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetTokenHoldersV2ForTokenAddressQueryParamOpts} queryParamOpts
* - `blockHeight`: Ending block to define a block range. Omitting this parameter defaults to the latest block height.
* - `pageSize`: Number of items per page. Note: Currently, only values of `100` and `1000` are supported. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
* - `date`: Ending date to define a block range (YYYY-MM-DD). Omitting this parameter defaults to the current date.
*
*/
async getTokenHoldersV2ForTokenAddressByPage(chainName, tokenAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/tokens/${tokenAddress}/token_holders_v2`, [
{
key: "block-height",
value: queryParamOpts?.blockHeight,
},
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
{
key: "date",
value: queryParamOpts?.date,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((balanceItem) => ({
...balanceItem,
balance: bigIntParser(balanceItem.balance),
total_supply: bigIntParser(balanceItem.total_supply),
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to fetch the historical native, fungible (ERC20), and non-fungible (ERC721 & ERC1155) tokens held by an address at a given block height or date. Response includes daily prices and other metadata.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} walletAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetHistoricalTokenBalancesForWalletAddressQueryParamOpts} queryParamOpts
* - `quoteCurrency`: The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, and `GBP`.
* - `nft`: If `true`, NFTs will be included in the response.
* - `noNftFetch`: If `true`, only NFTs that have been cached will be included in the response. Helpful for faster response times.
* - `noSpam`: If `true`, the suspected spam tokens are removed. Supports `eth-mainnet` and `matic-mainnet`.
* - `noNftAssetMetadata`: If `true`, the response shape is limited to a list of collections and token ids, omitting metadata and asset information. Helpful for faster response times and wallets holding a large number of NFTs.
* - `blockHeight`: Ending block to define a block range. Omitting this parameter defaults to the latest block height.
* - `date`: Ending date to define a block range (YYYY-MM-DD). Omitting this parameter defaults to the current date.
*
*/
async getHistoricalTokenBalancesForWalletAddress(chainName, walletAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/address/${walletAddress}/historical_balances`, [
{
key: "quote-currency",
value: queryParamOpts?.quoteCurrency,
},
{
key: "nft",
value: queryParamOpts?.nft,
},
{
key: "no-nft-fetch",
value: queryParamOpts?.noNftFetch,
},
{
key: "no-spam",
value: queryParamOpts?.noSpam,
},
{
key: "no-nft-asset-metadata",
value: queryParamOpts?.noNftAssetMetadata,
},
{
key: "block-height",
value: queryParamOpts?.blockHeight,
},
{
key: "date",
value: queryParamOpts?.date,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((balanceItem) => ({
...balanceItem,
balance: bigIntParser(balanceItem.balance),
last_transferred_at: balanceItem.last_transferred_at
? new Date(balanceItem.last_transferred_at)
: null,
nft_data: balanceItem.nft_data
? balanceItem.nft_data.map((nftItem) => ({
...nftItem,
token_id: bigIntParser(nftItem.token_id),
token_balance: bigIntParser(nftItem.token_balance),
token_price_wei: bigIntParser(nftItem.token_price_wei),
}))
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} walletAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetNativeTokenBalanceQueryParamOpts} queryParamOpts
* - `quoteCurrency`: The currency to convert. Supports `USD`, `CAD`, `EUR`, `SGD`, `INR`, `JPY`, `VND`, `CNY`, `KRW`, `RUB`, `TRY`, `NGN`, `ARS`, `AUD`, `CHF`, and `GBP`.
* - `blockHeight`: Ending block to define a block range. Omitting this parameter defaults to the latest block height.
*
*/
async getNativeTokenBalance(chainName, walletAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/address/${walletAddress}/balances_native`, [
{
key: "quote-currency",
value: queryParamOpts?.quoteCurrency,
},
{
key: "block-height",
value: queryParamOpts?.blockHeight,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((balanceItem) => ({
...balanceItem,
balance: bigIntParser(balanceItem.balance),
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
}
/**
* Base API
*
*/
class BaseService {
constructor(execution) {
this.execution = execution;
}
/**
*
* Commonly used to fetch and render a single block for a block explorer.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} blockHeight - The block height or `latest` for the latest block available.
*
*/
async getBlock(chainName, blockHeight) {
const endpoint = endpointGenerator(`${chainName}/block_v2/${blockHeight}`, []);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((blockItem) => ({
...blockItem,
signed_at: blockItem.signed_at
? new Date(blockItem.signed_at)
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to resolve ENS, RNS and Unstoppable Domains addresses.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} walletAddress - The requested address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
*
*/
async getResolvedAddress(chainName, walletAddress) {
const endpoint = endpointGenerator(`${chainName}/address/${walletAddress}/resolve_address`, []);
const parseData = (data) => {
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to get all the block heights within a particular date range. Useful for rendering a display where you sort blocks by day.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} startDate - The start date in YYYY-MM-DD format.
* @param {string | "latest"} endDate - The end date in YYYY-MM-DD format. Also accepts "latest" for the latest block height
* @param {GetBlockHeightsQueryParamOpts} queryParamOpts
* - `pageSize`: Number of items per page. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
*
*/
async *getBlockHeights(chainName, startDate, endDate, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/block_v2/${startDate}/${endDate}`, [
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((blockItem) => ({
...blockItem,
signed_at: blockItem.signed_at
? new Date(blockItem.signed_at)
: null,
}))
: null;
}
return data;
};
for await (const data of paginateEndpoint(endpoint, this.execution, parseData, "pagination")) {
yield data;
}
}
/**
*
* Commonly used to get all the block heights within a particular date range. Useful for rendering a display where you sort blocks by day.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} startDate - The start date in YYYY-MM-DD format.
* @param {string | "latest"} endDate - The end date in YYYY-MM-DD format. Also accepts "latest" for the latest block height
* @param {GetBlockHeightsQueryParamOpts} queryParamOpts
* - `pageSize`: Number of items per page. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
*
*/
async getBlockHeightsByPage(chainName, startDate, endDate, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/block_v2/${startDate}/${endDate}`, [
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((blockItem) => ({
...blockItem,
signed_at: blockItem.signed_at
? new Date(blockItem.signed_at)
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to get all the event logs of the latest block, or for a range of blocks. Includes sender contract metadata as well as decoded logs.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {GetLogsQueryParamOpts} queryParamOpts
* - `startingBlock`: The first block to retrieve log events with. Accepts decimals, hexadecimals, or the strings `earliest` and `latest`.
* - `endingBlock`: The last block to retrieve log events with. Accepts decimals, hexadecimals, or the strings `earliest` and `latest`.
* - `address`: The address of the log events sender contract.
* - `topics`: The topic hash(es) to retrieve logs with.
* - `blockHash`: The block hash to retrieve logs for.
* - `skipDecode`: Omit decoded log events.
*
*/
async getLogs(chainName, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/events`, [
{
key: "starting-block",
value: queryParamOpts?.startingBlock,
},
{
key: "ending-block",
value: queryParamOpts?.endingBlock,
},
{
key: "address",
value: queryParamOpts?.address,
},
{
key: "topics",
value: queryParamOpts?.topics,
},
{
key: "block-hash",
value: queryParamOpts?.blockHash,
},
{
key: "skip-decode",
value: queryParamOpts?.skipDecode,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((logItem) => ({
...logItem,
block_signed_at: logItem.block_signed_at
? new Date(logItem.block_signed_at)
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to get all the event logs emitted from a particular contract address. Useful for building dashboards that examine on-chain interactions.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} contractAddress - The requested contract address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetLogEventsByAddressQueryParamOpts} queryParamOpts
* - `startingBlock`: The first block to retrieve log events with. Accepts decimals, hexadecimals, or the strings `earliest` and `latest`.
* - `endingBlock`: The last block to retrieve log events with. Accepts decimals, hexadecimals, or the strings `earliest` and `latest`.
* - `pageSize`: Number of items per page. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
*
*/
async *getLogEventsByAddress(chainName, contractAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/events/address/${contractAddress}`, [
{
key: "starting-block",
value: queryParamOpts?.startingBlock,
},
{
key: "ending-block",
value: queryParamOpts?.endingBlock,
},
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((logItem) => ({
...logItem,
block_signed_at: logItem.block_signed_at
? new Date(logItem.block_signed_at)
: null,
}))
: null;
}
return data;
};
for await (const data of paginateEndpoint(endpoint, this.execution, parseData, "pagination")) {
yield data;
}
}
/**
*
* Commonly used to get all the event logs emitted from a particular contract address. Useful for building dashboards that examine on-chain interactions.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} contractAddress - The requested contract address. Passing in an `ENS`, `RNS`, `Lens Handle`, or an `Unstoppable Domain` resolves automatically.
* @param {GetLogEventsByAddressQueryParamOpts} queryParamOpts
* - `startingBlock`: The first block to retrieve log events with. Accepts decimals, hexadecimals, or the strings `earliest` and `latest`.
* - `endingBlock`: The last block to retrieve log events with. Accepts decimals, hexadecimals, or the strings `earliest` and `latest`.
* - `pageSize`: Number of items per page. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
*
*/
async getLogEventsByAddressByPage(chainName, contractAddress, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/events/address/${contractAddress}`, [
{
key: "starting-block",
value: queryParamOpts?.startingBlock,
},
{
key: "ending-block",
value: queryParamOpts?.endingBlock,
},
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((logItem) => ({
...logItem,
block_signed_at: logItem.block_signed_at
? new Date(logItem.block_signed_at)
: null,
}))
: null;
}
return data;
};
return await this.execution.execute(endpoint, parseData);
}
/**
*
* Commonly used to get all event logs of the same topic hash across all contracts within a particular chain. Useful for cross-sectional analysis of event logs that are emitted on-chain.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @param {string} topicHash - The endpoint will return event logs that contain this topic hash.
* @param {GetLogEventsByTopicHashQueryParamOpts} queryParamOpts
* - `startingBlock`: The first block to retrieve log events with. Accepts decimals, hexadecimals, or the strings `earliest` and `latest`.
* - `endingBlock`: The last block to retrieve log events with. Accepts decimals, hexadecimals, or the strings `earliest` and `latest`.
* - `secondaryTopics`: Additional topic hash(es) to filter on - padded & unpadded address fields are supported. Separate multiple topics with a comma.
* - `pageSize`: Number of items per page. Omitting this parameter defaults to 100.
* - `pageNumber`: 0-indexed page number to begin pagination.
*
*/
async *getLogEventsByTopicHash(chainName, topicHash, queryParamOpts) {
const endpoint = endpointGenerator(`${chainName}/events/topics/${topicHash}`, [
{
key: "starting-block",
value: queryParamOpts?.startingBlock,
},
{
key: "ending-block",
value: queryParamOpts?.endingBlock,
},
{
key: "secondary-topics",
value: queryParamOpts?.secondaryTopics,
},
{
key: "page-size",
value: queryParamOpts?.pageSize,
},
{
key: "page-number",
value: queryParamOpts?.pageNumber,
},
]);
const parseData = (data) => {
if (data.data) {
data.data.updated_at = data.data.updated_at
? new Date(data.data.updated_at)
: null;
data.data.items = data.data.items
? data.data.items.map((logItem) => ({
...logItem,
block_signed_at: logItem.block_signed_at
? new Date(logItem.block_signed_at)
: null,
}))
: null;
}
return data;
};
for await (const data of paginateEndpoint(endpoint, this.execution, parseData, "pagination")) {
yield data;
}
}
/**
*
* Commonly used to get all event logs of the same topic hash across all contracts within a particular chain. Useful for cross-sectional analysis of event logs that are emitted on-chain.
*
* @param {Chain} chainName - The chain name eg: `eth-mainnet` or 1.
* @para