@firefly-exchange/library-sui
Version:
Sui library housing helper methods, classes to interact with Bluefin protocol(s) deployed on Sui
151 lines (150 loc) • 6.19 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueryChain = void 0;
const clmm_1 = require("./clmm");
const bn_js_1 = __importDefault(require("bn.js"));
class QueryChain {
constructor(_suiClient) {
this.suiClient = _suiClient;
}
/// Returns pool state from chain
async getPool(id) {
const suiObjectResponse = await this.suiClient.getObject({
id: id,
options: { showContent: true }
});
const type = (suiObjectResponse.data?.content).type;
const coinTypes = type.replace(">", "").split("<")[1]?.split(/,\s*/) || [];
const fields = (suiObjectResponse.data?.content).fields;
const metadataA = await this.suiClient.getCoinMetadata({
coinType: coinTypes[0]
});
const metadataB = await this.suiClient.getCoinMetadata({
coinType: coinTypes[1]
});
return {
// identification
id: fields.id.id,
name: fields.name,
fee_rate: Number(fields.fee_rate),
// coins info
coin_a: {
address: coinTypes[0],
balance: fields.coin_a,
decimals: metadataA.decimals
},
coin_b: {
address: coinTypes[1],
balance: fields.coin_b,
decimals: metadataB.decimals
},
// liquidity, tick and price info
current_sqrt_price: fields.current_sqrt_price,
current_tick: Number((0, clmm_1.asIntN)(BigInt(fields.current_tick_index.fields.bits)).toString()),
liquidity: fields.liquidity,
// is pool paused
is_paused: fields.is_paused,
// managers
ticks_manager: fields.ticks_manager.fields,
observations_manager: fields.observations_manager.fields,
rewardsInfo: fields.reward_infos.map(info => {
info = info.fields;
return {
ended_at_seconds: Number(info.ended_at_seconds),
last_update_time: Number(info.last_update_time),
reward_coin_decimals: Number(info.reward_coin_decimals),
reward_coin_symbol: info.reward_coin_symbol,
reward_coin_type: info.reward_coin_type,
reward_growth_global: info.reward_growth_global,
reward_per_seconds: info.reward_per_seconds,
total_reward: Number(info.total_reward),
total_reward_allocated: Number(info.total_reward_allocated)
};
}),
protocol_fee_coin_a: Number(fields.protocol_fee_coin_a),
protocol_fee_coin_b: Number(fields.protocol_fee_coin_b)
};
}
/// Returns a pool's liquidity
async getPoolLiquidity(poolName) {
const poolState = await this.getPool(poolName);
return Number(poolState.liquidity);
}
/// Returns a pool's current price
async getPoolCurrentPrice(poolName) {
const poolState = await this.getPool(poolName);
return new bn_js_1.default(poolState.current_sqrt_price);
}
/// Returns
async getPoolCurrentTick(poolName) {
const poolState = await this.getPool(poolName);
return new bn_js_1.default(poolState.current_tick);
}
/// Returns the details of the provided position from chain
async getPositionDetails(id) {
const resp = await this.suiClient.getObject({
id,
options: {
showOwner: true,
showContent: true
}
});
return QueryChain.parsePositionObject(resp);
}
/**
* Returns a user's open position on bluefin spot protocol
* @param pkg The base package of the protocol (this is not CurrentPackage)
* @param user The address of the user for which to query positions
* @param pool (optional) The ID of the pool for which to query position.
* Defaults to none and returns all positions across all pools
* @returns Array<IPosition>
*/
async getUserPositions(pkg, user, pool) {
let positions = [];
const objType = `${pkg}::position::Position`;
let cursor = undefined;
let hasNextPage = true;
while (hasNextPage) {
const resp = await this.suiClient.getOwnedObjects({
owner: user,
cursor,
filter: {
MatchAll: [{ StructType: objType }]
},
options: {
showType: true,
showOwner: true,
showContent: true
}
});
hasNextPage = resp.hasNextPage;
cursor = resp.nextCursor;
positions = positions.concat(resp.data
.map(obj => {
return QueryChain.parsePositionObject(obj);
})
.filter(position => pool == undefined || position.pool_id == pool));
}
return positions;
}
static parsePositionObject(resp) {
const onChainPosition = resp.data.content.fields;
return {
owner: resp.data.owner.AddressOwner,
pool_id: onChainPosition.pool_id,
position_id: onChainPosition.id.id,
lower_tick: Number((0, clmm_1.asIntN)(BigInt(onChainPosition.lower_tick.fields.bits)).toString()),
upper_tick: Number((0, clmm_1.asIntN)(BigInt(onChainPosition.upper_tick.fields.bits)).toString()),
liquidity: Number(onChainPosition.liquidity),
fee_growth_coin_a: Number(onChainPosition.fee_growth_coin_a),
fee_growth_coin_b: Number(onChainPosition.fee_growth_coin_b),
fee_rate: Number(onChainPosition.fee_rate),
token_a_fee: Number(onChainPosition.token_a_fee),
token_b_fee: Number(onChainPosition.token_b_fee)
};
}
}
exports.QueryChain = QueryChain;
;