@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
JavaScript
;
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;