UNPKG

@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,112 lines (1,105 loc) 170 kB
'use strict'; 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