UNPKG

@stabilis/c9-shape-liquidity-getter

Version:

A library for calculating redemption values of concentrated liquidity positions for C9 shape liquidity.

168 lines (167 loc) 6.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getComponentData = exports.getNFTDataInChunks = exports.getNFTData = exports.getAllKeyValueStoreKeys = exports.fetchKeyValueStoreDataInChunks = exports.getGatewayApi = void 0; const babylon_gateway_api_sdk_1 = require("@radixdlt/babylon-gateway-api-sdk"); // C9 contracts only exist on Mainnet const NETWORK = babylon_gateway_api_sdk_1.RadixNetwork.Mainnet; // Helper function to break an array into chunks function chunkArray(array, chunkSize) { const chunks = []; if (chunkSize <= 0) { throw new Error("Chunk size must be greater than 0."); } for (let i = 0; i < array.length; i += chunkSize) { chunks.push(array.slice(i, i + chunkSize)); } return chunks; } // Initializes and returns a Gateway API client instance. const getGatewayApi = () => { return babylon_gateway_api_sdk_1.GatewayApiClient.initialize({ applicationName: "Radix Liquidity Calculator Lib", networkId: NETWORK, }); }; exports.getGatewayApi = getGatewayApi; /** * Fetches Key-Value Store data in chunks, accepting StateKeyValueStoreKeysResponseItem[] as input. * * @param keyValureStoreAddress - The component address of the key-value store. * @param keysToFetch - An array of StateKeyValueStoreKeysResponseItem (output from getAllKeyValueStoreKeys). * @param gatewayApi - The initialized Gateway API client. * @param ledgerState - The specific state version to query against (optional). * @param chunkSize - The number of keys to fetch in each chunk. * @returns A promise that resolves to an array of key-value store data items. */ const fetchKeyValueStoreDataInChunks = async (keyValureStoreAddress, keysToFetch, gatewayApi, ledgerState, chunkSize = 100) => { // Map StateKeyValueStoreKeysResponseItem to StateKeyValueStoreDataRequestKeyItem const sdkRequestKeys = keysToFetch.map((keyItem) => ({ key_hex: keyItem.key.raw_hex, })); const chunks = chunkArray(sdkRequestKeys, chunkSize); const chunkPromises = chunks.map((chunk) => gatewayApi.state.innerClient.keyValueStoreData({ stateKeyValueStoreDataRequest: { key_value_store_address: keyValureStoreAddress, keys: chunk, at_ledger_state: ledgerState, }, })); const chunkResponses = await Promise.all(chunkPromises); const allEntries = chunkResponses.flatMap((response) => response.entries); return allEntries; }; exports.fetchKeyValueStoreDataInChunks = fetchKeyValueStoreDataInChunks; /** * Fetches all keys from a Key-Value Store, handling pagination. * * @param api - The initialized Gateway API client. * @param keyValueStoreAddress - The component address of the key-value store. * @param ledgerState - The specific state version to query against (optional). * @returns A promise that resolves to an array of StateKeyValueStoreKeysResponseItem. */ const getAllKeyValueStoreKeys = async (api, keyValueStoreAddress, ledgerState) => { let allKeys = []; let currentCursor = undefined; let hasMore = true; // Keys retrieval in progress while (hasMore) { const response = await api.state.innerClient.keyValueStoreKeys({ stateKeyValueStoreKeysRequest: { key_value_store_address: keyValueStoreAddress, at_ledger_state: ledgerState, cursor: currentCursor, limit_per_page: 100, }, }); if (response.items && response.items.length > 0) { allKeys = allKeys.concat(response.items); } if (response.next_cursor) { currentCursor = response.next_cursor; } else { hasMore = false; } } return allKeys; }; exports.getAllKeyValueStoreKeys = getAllKeyValueStoreKeys; /** * Fetches Non-Fungible Token (NFT) data. * * @param api - The initialized Gateway API client. * @param nftAddress - The resource address of the NFT. * @param nftId - The ID of the NFT. * @param stateVersion - The specific state version to query against (optional). * @returns A promise that resolves to the NFT data. */ const getNFTData = async (api, nftAddress, nftId, stateVersion) => { const ledgerStateSelector = stateVersion ? { state_version: stateVersion } : undefined; const nftDataResponse = await api.state.getNonFungibleData(nftAddress, [nftId], ledgerStateSelector); return nftDataResponse; }; exports.getNFTData = getNFTData; /** * Fetches NFT data in chunks to avoid rate limiting * @param nftIds Array of NFT IDs to fetch * @param nftAddress The NFT resource address * @param api Gateway API client * @param stateVersion Optional state version * @param chunkSize Maximum number of NFTs to fetch in one request * @returns A record mapping NFT IDs to their data */ const getNFTDataInChunks = async (nftIds, nftAddress, api, stateVersion, chunkSize = 100) => { const chunks = chunkArray(nftIds, chunkSize); const allNftData = {}; for (const chunk of chunks) { const chunkPromises = chunk.map((nftId) => (0, exports.getNFTData)(api, nftAddress, nftId, stateVersion) .then((data) => ({ nftId, data: data?.[0]?.data?.programmatic_json })) .catch((error) => { // Error fetching NFT data, returning null for this NFT return { nftId, data: null }; })); const chunkResults = await Promise.all(chunkPromises); chunkResults.forEach(({ nftId, data }) => { if (data) { allNftData[nftId] = data; } }); // Add delay between chunks to avoid rate limiting if (chunks.indexOf(chunk) < chunks.length - 1) { await new Promise((resolve) => setTimeout(resolve, 1000)); } } return allNftData; }; exports.getNFTDataInChunks = getNFTDataInChunks; /** * Fetches detailed data for a component using getEntityDetailsVaultAggregated. * * @param api - The initialized Gateway API client. * @param componentAddress - The address of the component. * @param stateVersion - The specific state version to query against (optional). * @returns A promise that resolves to the component data, or null if not found. */ const getComponentData = async (api, componentAddress, stateVersion) => { const ledgerState = stateVersion ? { state_version: stateVersion } : undefined; const options = {}; try { const responseItems = await api.state.getEntityDetailsVaultAggregated([componentAddress], options, ledgerState); if (responseItems && responseItems.length > 0) { return responseItems[0]; } else { // No component data found return null; } } catch (error) { // Error with API call, propagate error throw error; } }; exports.getComponentData = getComponentData;