@stabilis/c9-shape-liquidity-getter
Version:
A library for calculating redemption values of concentrated liquidity positions for C9 shape liquidity.
106 lines (105 loc) • 4.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getC9BinData = getC9BinData;
const gateway_1 = require("../services/gateway");
const errors_1 = require("../types/errors");
const i192_1 = require("./i192");
async function getC9BinData(componentAddress, stateVersion, gatewayApi) {
try {
// Validate state version before proceeding
const currentStateVersion = await gatewayApi.status
.getCurrent()
.then((response) => response.ledger_state.state_version);
if (stateVersion > currentStateVersion) {
throw errors_1.DataError.stateVersionTooHigh(stateVersion);
}
const ledgerState = { state_version: stateVersion };
// 1. Get component data
const componentData = await (0, gateway_1.getComponentData)(gatewayApi, componentAddress, stateVersion);
if (!componentData) {
console.error("Component data not found");
return null;
}
// 2. Extract all needed fields from component state
const state = componentData.details?.state;
if (!state?.fields) {
console.error("Invalid component state");
return null;
}
// Find required fields
const binMapField = state.fields.find((f) => f.field_name === "bin_map");
const tickIndexField = state.fields.find((f) => f.field_name === "tick_index");
const nftManagerField = state.fields.find((f) => f.field_name === "liquidity_receipt_manager");
const activeXField = state.fields.find((f) => f.field_name === "active_x");
const activeYField = state.fields.find((f) => f.field_name === "active_y");
const activeTotalClaimField = state.fields.find((f) => f.field_name === "active_total_claim");
const binSpanField = state.fields.find((f) => f.field_name === "bin_span");
if (!binMapField?.value ||
!nftManagerField?.value ||
!activeXField?.value ||
!activeYField?.value ||
!activeTotalClaimField?.value ||
!binSpanField?.value) {
console.error("Required fields not found in component state");
return null;
}
// Extract current tick if available
const currentTickField = tickIndexField?.fields?.find((f) => f.field_name === "current")?.fields?.[0]?.fields?.[0]?.value;
const currentTick = currentTickField
? parseInt(currentTickField)
: undefined;
// Extract bin span
const binSpan = parseInt(binSpanField.value);
if (isNaN(binSpan)) {
console.error("Invalid bin span value");
return null;
}
const kvStoreAddress = binMapField.value;
// 3. Get all keys from the KV store
const keys = await (0, gateway_1.getAllKeyValueStoreKeys)(gatewayApi, kvStoreAddress, ledgerState);
// 4. Fetch the actual data for all keys
const rawBinMapData = await (0, gateway_1.fetchKeyValueStoreDataInChunks)(kvStoreAddress, keys, gatewayApi, ledgerState);
// 5. Transform the data into a dictionary
const binMapData = {};
for (const entry of rawBinMapData) {
const keyJson = entry.key.programmatic_json;
const valueJson = entry.value.programmatic_json;
const tick = keyJson?.fields?.[0]?.value;
if (tick && valueJson?.fields) {
const fields = valueJson.fields;
const amount = fields.find((f) => f.field_name === "amount")?.value ||
"0";
const totalClaim = fields.find((f) => f.field_name === "total_claim")
?.value || "0";
// Process the values using I192, but store as string for API compatibility
const amountI192 = new i192_1.I192(amount);
const totalClaimI192 = new i192_1.I192(totalClaim);
binMapData[parseInt(tick)] = {
amount: amountI192.toString(),
total_claim: totalClaimI192.toString(),
};
}
}
// Process active X and Y values using I192
const activeX = new i192_1.I192(activeXField.value);
const activeY = new i192_1.I192(activeYField.value);
const activeTotalClaim = new i192_1.I192(activeTotalClaimField.value);
return {
componentData,
binMapData,
nftAddress: nftManagerField.value,
currentTick,
active_x: activeX.toString(),
active_y: activeY.toString(),
active_total_claim: activeTotalClaim.toString(),
binSpan,
};
}
catch (error) {
if (error instanceof errors_1.DataError) {
throw error;
}
console.error("Error in getC9BinData:", error);
throw error;
}
}